r560: Fix bugzilla 1279: cannot control individual print jobs using cups
[Samba/gebeck_regimport.git] / source3 / printing / printing.c
blob2355dd14506bac1acc73639a37a01617cb934507
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 /* Current printer interface */
27 static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
29 /*
30 the printing backend revolves around a tdb database that stores the
31 SMB view of the print queue
33 The key for this database is a jobid - a internally generated number that
34 uniquely identifies a print job
36 reading the print queue involves two steps:
37 - possibly running lpq and updating the internal database from that
38 - reading entries from the database
40 jobids are assigned when a job starts spooling.
43 /***************************************************************************
44 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
45 bit RPC jobids.... JRA.
46 ***************************************************************************/
48 static TDB_CONTEXT *rap_tdb;
49 static uint16 next_rap_jobid;
51 uint16 pjobid_to_rap(int snum, uint32 jobid)
53 uint16 rap_jobid;
54 TDB_DATA data, key;
55 char jinfo[8];
57 DEBUG(10,("pjobid_to_rap: called.\n"));
59 if (!rap_tdb) {
60 /* Create the in-memory tdb. */
61 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
62 if (!rap_tdb)
63 return 0;
66 SIVAL(&jinfo,0,(int32)snum);
67 SIVAL(&jinfo,4,jobid);
69 key.dptr = (char *)&jinfo;
70 key.dsize = sizeof(jinfo);
71 data = tdb_fetch(rap_tdb, key);
72 if (data.dptr && data.dsize == sizeof(uint16)) {
73 rap_jobid = SVAL(data.dptr, 0);
74 SAFE_FREE(data.dptr);
75 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
76 (unsigned int)jobid,
77 (unsigned int)rap_jobid));
78 return rap_jobid;
80 SAFE_FREE(data.dptr);
81 /* Not found - create and store mapping. */
82 rap_jobid = ++next_rap_jobid;
83 if (rap_jobid == 0)
84 rap_jobid = ++next_rap_jobid;
85 data.dptr = (char *)&rap_jobid;
86 data.dsize = sizeof(rap_jobid);
87 tdb_store(rap_tdb, key, data, TDB_REPLACE);
88 tdb_store(rap_tdb, data, key, TDB_REPLACE);
90 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
91 (unsigned int)jobid,
92 (unsigned int)rap_jobid));
93 return rap_jobid;
96 BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
98 TDB_DATA data, key;
100 DEBUG(10,("rap_to_pjobid called.\n"));
102 if (!rap_tdb)
103 return False;
105 key.dptr = (char *)&rap_jobid;
106 key.dsize = sizeof(rap_jobid);
107 data = tdb_fetch(rap_tdb, key);
108 if (data.dptr && data.dsize == 8) {
109 *psnum = IVAL(data.dptr,0);
110 *pjobid = IVAL(data.dptr,4);
111 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
112 (unsigned int)*pjobid,
113 (unsigned int)rap_jobid));
114 SAFE_FREE(data.dptr);
115 return True;
118 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
119 (unsigned int)rap_jobid));
120 SAFE_FREE(data.dptr);
121 return False;
124 static void rap_jobid_delete(int snum, uint32 jobid)
126 TDB_DATA key, data;
127 uint16 rap_jobid;
128 char jinfo[8];
130 DEBUG(10,("rap_jobid_delete: called.\n"));
132 if (!rap_tdb)
133 return;
135 SIVAL(&jinfo,0,(int32)snum);
136 SIVAL(&jinfo,4,jobid);
138 key.dptr = (char *)&jinfo;
139 key.dsize = sizeof(jinfo);
140 data = tdb_fetch(rap_tdb, key);
141 if (!data.dptr || (data.dsize != sizeof(uint16))) {
142 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
143 (unsigned int)jobid ));
144 SAFE_FREE(data.dptr);
145 return;
148 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
149 (unsigned int)jobid ));
151 rap_jobid = SVAL(data.dptr, 0);
152 SAFE_FREE(data.dptr);
153 data.dptr = (char *)&rap_jobid;
154 data.dsize = sizeof(rap_jobid);
155 tdb_delete(rap_tdb, key);
156 tdb_delete(rap_tdb, data);
159 static pid_t local_pid;
161 static int get_queue_status(int, print_status_struct *);
163 /****************************************************************************
164 Initialise the printing backend. Called once at startup before the fork().
165 ****************************************************************************/
167 BOOL print_backend_init(void)
169 const char *sversion = "INFO/version";
170 pstring printing_path;
171 int services = lp_numservices();
172 int snum;
174 if (local_pid == sys_getpid())
175 return True;
177 unlink(lock_path("printing.tdb"));
178 pstrcpy(printing_path,lock_path("printing"));
179 mkdir(printing_path,0755);
181 local_pid = sys_getpid();
183 /* handle a Samba upgrade */
185 for (snum = 0; snum < services; snum++) {
186 struct tdb_print_db *pdb;
187 if (!lp_print_ok(snum))
188 continue;
190 pdb = get_print_db_byname(lp_const_servicename(snum));
191 if (!pdb)
192 continue;
193 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
194 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
195 release_print_db(pdb);
196 return False;
198 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
199 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
200 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
202 tdb_unlock_bystring(pdb->tdb, sversion);
203 release_print_db(pdb);
206 close_all_print_db(); /* Don't leave any open. */
208 /* do NT print initialization... */
209 return nt_printing_init();
212 /****************************************************************************
213 Shut down printing backend. Called once at shutdown to close the tdb.
214 ****************************************************************************/
216 void printing_end(void)
218 close_all_print_db(); /* Don't leave any open. */
221 /****************************************************************************
222 Retrieve the set of printing functions for a given service. This allows
223 us to set the printer function table based on the value of the 'printing'
224 service parameter.
226 Use the generic interface as the default and only use cups interface only
227 when asked for (and only when supported)
228 ****************************************************************************/
230 static struct printif *get_printer_fns( int snum )
232 struct printif *printer_fns = &generic_printif;
234 #ifdef HAVE_CUPS
235 if ( lp_printing(snum) == PRINT_CUPS ) {
236 printer_fns = &cups_printif;
238 #endif /* HAVE_CUPS */
240 return printer_fns;
243 /****************************************************************************
244 Useful function to generate a tdb key.
245 ****************************************************************************/
247 static TDB_DATA print_key(uint32 jobid)
249 static uint32 j;
250 TDB_DATA ret;
252 SIVAL(&j, 0, jobid);
253 ret.dptr = (void *)&j;
254 ret.dsize = sizeof(j);
255 return ret;
258 /***********************************************************************
259 unpack a pjob from a tdb buffer
260 ***********************************************************************/
262 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
264 int len = 0;
265 int used;
266 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
267 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
269 if ( !buf || !pjob )
270 return -1;
272 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
273 &pjpid,
274 &pjsysjob,
275 &pjfd,
276 &pjstarttime,
277 &pjstatus,
278 &pjsize,
279 &pjpage_count,
280 &pjspooled,
281 &pjsmbjob,
282 pjob->filename,
283 pjob->jobname,
284 pjob->user,
285 pjob->queuename);
287 if ( len == -1 )
288 return -1;
290 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
291 return -1;
293 len += used;
295 pjob->pid = pjpid;
296 pjob->sysjob = pjsysjob;
297 pjob->fd = pjfd;
298 pjob->starttime = pjstarttime;
299 pjob->status = pjstatus;
300 pjob->size = pjsize;
301 pjob->page_count = pjpage_count;
302 pjob->spooled = pjspooled;
303 pjob->smbjob = pjsmbjob;
305 return len;
309 /****************************************************************************
310 Useful function to find a print job in the database.
311 ****************************************************************************/
313 static struct printjob *print_job_find(int snum, uint32 jobid)
315 static struct printjob pjob;
316 TDB_DATA ret;
317 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
320 if (!pdb)
321 return NULL;
323 ret = tdb_fetch(pdb->tdb, print_key(jobid));
324 release_print_db(pdb);
326 if (!ret.dptr)
327 return NULL;
329 if ( pjob.nt_devmode )
330 free_nt_devicemode( &pjob.nt_devmode );
332 ZERO_STRUCT( pjob );
334 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
335 SAFE_FREE(ret.dptr);
336 return NULL;
339 SAFE_FREE(ret.dptr);
340 return &pjob;
343 /* Convert a unix jobid to a smb jobid */
345 static uint32 sysjob_to_jobid_value;
347 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
348 TDB_DATA data, void *state)
350 struct printjob *pjob;
351 int *sysjob = (int *)state;
353 if (!data.dptr || data.dsize == 0)
354 return 0;
356 pjob = (struct printjob *)data.dptr;
357 if (key.dsize != sizeof(uint32))
358 return 0;
360 if (*sysjob == pjob->sysjob) {
361 uint32 jobid = IVAL(key.dptr,0);
363 sysjob_to_jobid_value = jobid;
364 return 1;
367 return 0;
370 /****************************************************************************
371 This is a *horribly expensive call as we have to iterate through all the
372 current printer tdb's. Don't do this often ! JRA.
373 ****************************************************************************/
375 uint32 sysjob_to_jobid(int unix_jobid)
377 int services = lp_numservices();
378 int snum;
380 sysjob_to_jobid_value = (uint32)-1;
382 for (snum = 0; snum < services; snum++) {
383 struct tdb_print_db *pdb;
384 if (!lp_print_ok(snum))
385 continue;
386 pdb = get_print_db_byname(lp_const_servicename(snum));
387 if (pdb)
388 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
389 release_print_db(pdb);
390 if (sysjob_to_jobid_value != (uint32)-1)
391 return sysjob_to_jobid_value;
393 return (uint32)-1;
396 /****************************************************************************
397 Send notifications based on what has changed after a pjob_store.
398 ****************************************************************************/
400 static struct {
401 uint32 lpq_status;
402 uint32 spoolss_status;
403 } lpq_to_spoolss_status_map[] = {
404 { LPQ_QUEUED, JOB_STATUS_QUEUED },
405 { LPQ_PAUSED, JOB_STATUS_PAUSED },
406 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
407 { LPQ_PRINTING, JOB_STATUS_PRINTING },
408 { LPQ_DELETING, JOB_STATUS_DELETING },
409 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
410 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
411 { LPQ_PRINTED, JOB_STATUS_PRINTED },
412 { LPQ_DELETED, JOB_STATUS_DELETED },
413 { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
414 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
415 { -1, 0 }
418 /* Convert a lpq status value stored in printing.tdb into the
419 appropriate win32 API constant. */
421 static uint32 map_to_spoolss_status(uint32 lpq_status)
423 int i = 0;
425 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
426 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
427 return lpq_to_spoolss_status_map[i].spoolss_status;
428 i++;
431 return 0;
434 static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
435 struct printjob *new_data)
437 BOOL new_job = False;
439 if (!old_data)
440 new_job = True;
442 /* Notify the job name first */
444 if (new_job || !strequal(old_data->jobname, new_data->jobname))
445 notify_job_name(snum, jobid, new_data->jobname);
447 /* Job attributes that can't be changed. We only send
448 notification for these on a new job. */
450 if (new_job) {
451 notify_job_submitted(snum, jobid, new_data->starttime);
452 notify_job_username(snum, jobid, new_data->user);
455 /* Job attributes of a new job or attributes that can be
456 modified. */
458 if (new_job || old_data->status != new_data->status)
459 notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
461 if (new_job || old_data->size != new_data->size)
462 notify_job_total_bytes(snum, jobid, new_data->size);
464 if (new_job || old_data->page_count != new_data->page_count)
465 notify_job_total_pages(snum, jobid, new_data->page_count);
468 /****************************************************************************
469 Store a job structure back to the database.
470 ****************************************************************************/
472 static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
474 TDB_DATA old_data, new_data;
475 BOOL ret = False;
476 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
477 char *buf = NULL;
478 int len, newlen, buflen;
481 if (!pdb)
482 return False;
484 /* Get old data */
486 old_data = tdb_fetch(pdb->tdb, print_key(jobid));
488 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
490 newlen = 0;
492 do {
493 len = 0;
494 buflen = newlen;
495 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
496 (uint32)pjob->pid,
497 (uint32)pjob->sysjob,
498 (uint32)pjob->fd,
499 (uint32)pjob->starttime,
500 (uint32)pjob->status,
501 (uint32)pjob->size,
502 (uint32)pjob->page_count,
503 (uint32)pjob->spooled,
504 (uint32)pjob->smbjob,
505 pjob->filename,
506 pjob->jobname,
507 pjob->user,
508 pjob->queuename);
510 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
512 if (buflen != len) {
513 char *tb;
515 tb = (char *)Realloc(buf, len);
516 if (!tb) {
517 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
518 goto done;
520 else
521 buf = tb;
522 newlen = len;
524 } while ( buflen != len );
527 /* Store new data */
529 new_data.dptr = buf;
530 new_data.dsize = len;
531 ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
533 release_print_db(pdb);
535 /* Send notify updates for what has changed */
537 if ( ret ) {
538 struct printjob old_pjob;
540 if ( old_data.dsize )
542 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
544 pjob_store_notify( snum, jobid, &old_pjob , pjob );
545 free_nt_devicemode( &old_pjob.nt_devmode );
548 else {
549 /* new job */
550 pjob_store_notify( snum, jobid, NULL, pjob );
554 done:
555 SAFE_FREE( old_data.dptr );
556 SAFE_FREE( buf );
558 return ret;
561 /****************************************************************************
562 Remove a job structure from the database.
563 ****************************************************************************/
565 void pjob_delete(int snum, uint32 jobid)
567 struct printjob *pjob = print_job_find(snum, jobid);
568 uint32 job_status = 0;
569 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
571 if (!pdb)
572 return;
574 if (!pjob) {
575 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
576 (unsigned int)jobid));
577 release_print_db(pdb);
578 return;
581 /* Send a notification that a job has been deleted */
583 job_status = map_to_spoolss_status(pjob->status);
585 /* We must cycle through JOB_STATUS_DELETING and
586 JOB_STATUS_DELETED for the port monitor to delete the job
587 properly. */
589 job_status |= JOB_STATUS_DELETING;
590 notify_job_status(snum, jobid, job_status);
592 job_status |= JOB_STATUS_DELETED;
593 notify_job_status(snum, jobid, job_status);
595 /* Remove from printing.tdb */
597 tdb_delete(pdb->tdb, print_key(jobid));
598 release_print_db(pdb);
599 rap_jobid_delete(snum, jobid);
602 /****************************************************************************
603 Parse a file name from the system spooler to generate a jobid.
604 ****************************************************************************/
606 static uint32 print_parse_jobid(char *fname)
608 int jobid;
610 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
611 return (uint32)-1;
612 fname += strlen(PRINT_SPOOL_PREFIX);
614 jobid = atoi(fname);
615 if (jobid <= 0)
616 return (uint32)-1;
618 return (uint32)jobid;
621 /****************************************************************************
622 List a unix job in the print database.
623 ****************************************************************************/
625 static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
627 struct printjob pj, *old_pj;
629 if (jobid == (uint32)-1)
630 jobid = q->job + UNIX_JOB_START;
632 /* Preserve the timestamp on an existing unix print job */
634 old_pj = print_job_find(snum, jobid);
636 ZERO_STRUCT(pj);
638 pj.pid = (pid_t)-1;
639 pj.sysjob = q->job;
640 pj.fd = -1;
641 pj.starttime = old_pj ? old_pj->starttime : q->time;
642 pj.status = q->status;
643 pj.size = q->size;
644 pj.spooled = True;
645 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
646 if (jobid < UNIX_JOB_START) {
647 pj.smbjob = True;
648 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
649 } else {
650 pj.smbjob = False;
651 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
653 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
654 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
656 pjob_store(snum, jobid, &pj);
660 struct traverse_struct {
661 print_queue_struct *queue;
662 int qcount, snum, maxcount, total_jobs;
663 time_t lpq_time;
666 /****************************************************************************
667 Utility fn to delete any jobs that are no longer active.
668 ****************************************************************************/
670 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
672 struct traverse_struct *ts = (struct traverse_struct *)state;
673 struct printjob pjob;
674 uint32 jobid;
675 int i = 0;
677 if ( key.dsize != sizeof(jobid) )
678 return 0;
680 jobid = IVAL(key.dptr, 0);
681 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
682 return 0;
683 free_nt_devicemode( &pjob.nt_devmode );
686 if (ts->snum != lp_servicenumber(pjob.queuename)) {
687 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
688 return 0;
691 if (!pjob.smbjob) {
692 /* remove a unix job if it isn't in the system queue any more */
694 for (i=0;i<ts->qcount;i++) {
695 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
696 if (jobid == u_jobid)
697 break;
699 if (i == ts->qcount) {
700 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
701 (unsigned int)jobid ));
702 pjob_delete(ts->snum, jobid);
703 return 0;
706 /* need to continue the the bottom of the function to
707 save the correct attributes */
710 /* maybe it hasn't been spooled yet */
711 if (!pjob.spooled) {
712 /* if a job is not spooled and the process doesn't
713 exist then kill it. This cleans up after smbd
714 deaths */
715 if (!process_exists(pjob.pid)) {
716 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
717 (unsigned int)jobid, (unsigned int)pjob.pid ));
718 pjob_delete(ts->snum, jobid);
719 } else
720 ts->total_jobs++;
721 return 0;
724 /* this check only makes sense for jobs submitted from Windows clients */
726 if ( pjob.smbjob ) {
727 for (i=0;i<ts->qcount;i++) {
728 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
729 if (jobid == curr_jobid)
730 break;
734 /* The job isn't in the system queue - we have to assume it has
735 completed, so delete the database entry. */
737 if (i == ts->qcount) {
739 /* A race can occur between the time a job is spooled and
740 when it appears in the lpq output. This happens when
741 the job is added to printing.tdb when another smbd
742 running print_queue_update() has completed a lpq and
743 is currently traversing the printing tdb and deleting jobs.
744 Don't delete the job if it was submitted after the lpq_time. */
746 if (pjob.starttime < ts->lpq_time) {
747 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
748 (unsigned int)jobid,
749 (unsigned int)pjob.starttime,
750 (unsigned int)ts->lpq_time ));
751 pjob_delete(ts->snum, jobid);
752 } else
753 ts->total_jobs++;
754 return 0;
757 /* Save the pjob attributes we will store. */
758 /* FIXME!!! This is the only place where queue->job
759 represents the SMB jobid --jerry */
760 ts->queue[i].job = jobid;
761 ts->queue[i].size = pjob.size;
762 ts->queue[i].page_count = pjob.page_count;
763 ts->queue[i].status = pjob.status;
764 ts->queue[i].priority = 1;
765 ts->queue[i].time = pjob.starttime;
766 fstrcpy(ts->queue[i].fs_user, pjob.user);
767 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
769 ts->total_jobs++;
771 return 0;
774 /****************************************************************************
775 Check if the print queue has been updated recently enough.
776 ****************************************************************************/
778 static void print_cache_flush(int snum)
780 fstring key;
781 const char *printername = lp_const_servicename(snum);
782 struct tdb_print_db *pdb = get_print_db_byname(printername);
784 if (!pdb)
785 return;
786 slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
787 tdb_store_int32(pdb->tdb, key, -1);
788 release_print_db(pdb);
791 /****************************************************************************
792 Check if someone already thinks they are doing the update.
793 ****************************************************************************/
795 static pid_t get_updating_pid(fstring printer_name)
797 fstring keystr;
798 TDB_DATA data, key;
799 pid_t updating_pid;
800 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
802 if (!pdb)
803 return (pid_t)-1;
804 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
805 key.dptr = keystr;
806 key.dsize = strlen(keystr);
808 data = tdb_fetch(pdb->tdb, key);
809 release_print_db(pdb);
810 if (!data.dptr || data.dsize != sizeof(pid_t)) {
811 SAFE_FREE(data.dptr);
812 return (pid_t)-1;
815 updating_pid = IVAL(data.dptr, 0);
816 SAFE_FREE(data.dptr);
818 if (process_exists(updating_pid))
819 return updating_pid;
821 return (pid_t)-1;
824 /****************************************************************************
825 Set the fact that we're doing the update, or have finished doing the update
826 in the tdb.
827 ****************************************************************************/
829 static void set_updating_pid(const fstring printer_name, BOOL delete)
831 fstring keystr;
832 TDB_DATA key;
833 TDB_DATA data;
834 pid_t updating_pid = sys_getpid();
835 uint8 buffer[4];
837 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
839 if (!pdb)
840 return;
842 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
843 key.dptr = keystr;
844 key.dsize = strlen(keystr);
846 if (delete) {
847 tdb_delete(pdb->tdb, key);
848 release_print_db(pdb);
849 return;
852 SIVAL( buffer, 0, updating_pid);
853 data.dptr = (void *)buffer;
854 data.dsize = 4; /* we always assume this is a 4 byte value */
856 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
857 release_print_db(pdb);
860 /****************************************************************************
861 Sort print jobs by submittal time.
862 ****************************************************************************/
864 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
866 /* Silly cases */
868 if (!j1 && !j2)
869 return 0;
870 if (!j1)
871 return -1;
872 if (!j2)
873 return 1;
875 /* Sort on job start time */
877 if (j1->time == j2->time)
878 return 0;
879 return (j1->time > j2->time) ? 1 : -1;
882 /****************************************************************************
883 Store the sorted queue representation for later portmon retrieval.
884 ****************************************************************************/
886 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
888 TDB_DATA data, key;
889 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
890 print_queue_struct *queue = pts->queue;
891 size_t len;
892 size_t i;
893 uint qcount;
895 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
896 pts->qcount = max_reported_jobs;
897 qcount = pts->qcount;
899 /* Work out the size. */
900 data.dsize = 0;
901 data.dsize += tdb_pack(NULL, 0, "d", qcount);
903 for (i = 0; i < pts->qcount; i++) {
904 data.dsize += tdb_pack(NULL, 0, "ddddddff",
905 (uint32)queue[i].job,
906 (uint32)queue[i].size,
907 (uint32)queue[i].page_count,
908 (uint32)queue[i].status,
909 (uint32)queue[i].priority,
910 (uint32)queue[i].time,
911 queue[i].fs_user,
912 queue[i].fs_file);
915 if ((data.dptr = malloc(data.dsize)) == NULL)
916 return;
918 len = 0;
919 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
920 for (i = 0; i < pts->qcount; i++) {
921 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
922 (uint32)queue[i].job,
923 (uint32)queue[i].size,
924 (uint32)queue[i].page_count,
925 (uint32)queue[i].status,
926 (uint32)queue[i].priority,
927 (uint32)queue[i].time,
928 queue[i].fs_user,
929 queue[i].fs_file);
932 key.dptr = "INFO/linear_queue_array";
933 key.dsize = strlen(key.dptr);
934 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
935 SAFE_FREE(data.dptr);
936 return;
939 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
941 TDB_DATA data, key;
943 key.dptr = "INFO/jobs_changed";
944 key.dsize = strlen(key.dptr);
945 ZERO_STRUCT(data);
947 data = tdb_fetch(pdb->tdb, key);
948 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
949 SAFE_FREE(data.dptr);
950 ZERO_STRUCT(data);
953 return data;
956 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
958 unsigned int i;
959 unsigned int job_count = data.dsize / 4;
961 for (i = 0; i < job_count; i++) {
962 uint32 ch_jobid;
964 ch_jobid = IVAL(data.dptr, i*4);
965 if (ch_jobid == jobid)
966 remove_from_jobs_changed(snum, jobid);
970 /****************************************************************************
971 Update the internal database from the system print queue for a queue.
972 ****************************************************************************/
974 static void print_queue_update(int snum)
976 int i, qcount;
977 print_queue_struct *queue = NULL;
978 print_status_struct status;
979 print_status_struct old_status;
980 struct printjob *pjob;
981 struct traverse_struct tstruct;
982 fstring keystr, printer_name, cachestr;
983 TDB_DATA data, key;
984 TDB_DATA jcdata;
985 struct tdb_print_db *pdb;
986 struct printif *current_printif = get_printer_fns( snum );
988 fstrcpy(printer_name, lp_const_servicename(snum));
989 pdb = get_print_db_byname(printer_name);
990 if (!pdb)
991 return;
994 * Check to see if someone else is doing this update.
995 * This is essentially a mutex on the update.
998 if (get_updating_pid(printer_name) != -1) {
999 release_print_db(pdb);
1000 return;
1003 /* Lock the queue for the database update */
1005 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
1006 /* Only wait 10 seconds for this. */
1007 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1008 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
1009 release_print_db(pdb);
1010 return;
1014 * Ensure that no one else got in here.
1015 * If the updating pid is still -1 then we are
1016 * the winner.
1019 if (get_updating_pid(printer_name) != -1) {
1021 * Someone else is doing the update, exit.
1023 tdb_unlock_bystring(pdb->tdb, keystr);
1024 release_print_db(pdb);
1025 return;
1029 * We're going to do the update ourselves.
1032 /* Tell others we're doing the update. */
1033 set_updating_pid(printer_name, False);
1036 * Allow others to enter and notice we're doing
1037 * the update.
1040 tdb_unlock_bystring(pdb->tdb, keystr);
1043 * Update the cache time FIRST ! Stops others even
1044 * attempting to get the lock and doing this
1045 * if the lpq takes a long time.
1048 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
1049 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1051 /* get the current queue using the appropriate interface */
1052 ZERO_STRUCT(status);
1054 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
1056 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1057 "s" : "", printer_name));
1059 /* Sort the queue by submission time otherwise they are displayed
1060 in hash order. */
1062 qsort(queue, qcount, sizeof(print_queue_struct),
1063 QSORT_CAST(printjob_comp));
1066 any job in the internal database that is marked as spooled
1067 and doesn't exist in the system queue is considered finished
1068 and removed from the database
1070 any job in the system database but not in the internal database
1071 is added as a unix job
1073 fill in any system job numbers as we go
1076 jcdata = get_jobs_changed_data(pdb);
1078 for (i=0; i<qcount; i++) {
1079 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1081 if (jobid == (uint32)-1) {
1082 /* assume its a unix print job */
1083 print_unix_job(snum, &queue[i], jobid);
1084 continue;
1087 /* we have an active SMB print job - update its status */
1088 pjob = print_job_find(snum, jobid);
1089 if (!pjob) {
1090 /* err, somethings wrong. Probably smbd was restarted
1091 with jobs in the queue. All we can do is treat them
1092 like unix jobs. Pity. */
1093 print_unix_job(snum, &queue[i], jobid);
1094 continue;
1097 pjob->sysjob = queue[i].job;
1098 pjob->status = queue[i].status;
1099 pjob_store(snum, jobid, pjob);
1100 check_job_changed(snum, jcdata, jobid);
1103 SAFE_FREE(jcdata.dptr);
1105 /* now delete any queued entries that don't appear in the
1106 system queue */
1107 tstruct.queue = queue;
1108 tstruct.qcount = qcount;
1109 tstruct.snum = snum;
1110 tstruct.total_jobs = 0;
1111 tstruct.lpq_time = time(NULL);
1113 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1115 /* Store the linearised queue, max jobs only. */
1116 store_queue_struct(pdb, &tstruct);
1118 SAFE_FREE(tstruct.queue);
1120 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1121 printer_name, tstruct.total_jobs ));
1123 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1125 get_queue_status(snum, &old_status);
1126 if (old_status.qcount != qcount)
1127 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1128 old_status.qcount, qcount, printer_name ));
1130 /* store the new queue status structure */
1131 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1132 key.dptr = keystr;
1133 key.dsize = strlen(keystr);
1135 status.qcount = qcount;
1136 data.dptr = (void *)&status;
1137 data.dsize = sizeof(status);
1138 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1141 * Update the cache time again. We want to do this call
1142 * as little as possible...
1145 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1146 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1148 /* Delete our pid from the db. */
1149 set_updating_pid(printer_name, True);
1150 release_print_db(pdb);
1153 /****************************************************************************
1154 Create/Update an entry in the print tdb that will allow us to send notify
1155 updates only to interested smbd's.
1156 ****************************************************************************/
1158 BOOL print_notify_register_pid(int snum)
1160 TDB_DATA data;
1161 struct tdb_print_db *pdb = NULL;
1162 TDB_CONTEXT *tdb = NULL;
1163 const char *printername;
1164 uint32 mypid = (uint32)sys_getpid();
1165 BOOL ret = False;
1166 size_t i;
1168 /* if (snum == -1), then the change notify request was
1169 on a print server handle and we need to register on
1170 all print queus */
1172 if (snum == -1)
1174 int num_services = lp_numservices();
1175 int idx;
1177 for ( idx=0; idx<num_services; idx++ ) {
1178 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1179 print_notify_register_pid(idx);
1182 return True;
1184 else /* register for a specific printer */
1186 printername = lp_const_servicename(snum);
1187 pdb = get_print_db_byname(printername);
1188 if (!pdb)
1189 return False;
1190 tdb = pdb->tdb;
1193 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1194 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1195 printername));
1196 if (pdb)
1197 release_print_db(pdb);
1198 return False;
1201 data = get_printer_notify_pid_list( tdb, printername, True );
1203 /* Add ourselves and increase the refcount. */
1205 for (i = 0; i < data.dsize; i += 8) {
1206 if (IVAL(data.dptr,i) == mypid) {
1207 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1208 SIVAL(data.dptr, i+4, new_refcount);
1209 break;
1213 if (i == data.dsize) {
1214 /* We weren't in the list. Realloc. */
1215 data.dptr = Realloc(data.dptr, data.dsize + 8);
1216 if (!data.dptr) {
1217 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1218 printername));
1219 goto done;
1221 data.dsize += 8;
1222 SIVAL(data.dptr,data.dsize - 8,mypid);
1223 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1226 /* Store back the record. */
1227 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1228 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1229 list for printer %s\n", printername));
1230 goto done;
1233 ret = True;
1235 done:
1237 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1238 if (pdb)
1239 release_print_db(pdb);
1240 SAFE_FREE(data.dptr);
1241 return ret;
1244 /****************************************************************************
1245 Update an entry in the print tdb that will allow us to send notify
1246 updates only to interested smbd's.
1247 ****************************************************************************/
1249 BOOL print_notify_deregister_pid(int snum)
1251 TDB_DATA data;
1252 struct tdb_print_db *pdb = NULL;
1253 TDB_CONTEXT *tdb = NULL;
1254 const char *printername;
1255 uint32 mypid = (uint32)sys_getpid();
1256 size_t i;
1257 BOOL ret = False;
1259 /* if ( snum == -1 ), we are deregister a print server handle
1260 which means to deregister on all print queues */
1262 if (snum == -1)
1264 int num_services = lp_numservices();
1265 int idx;
1267 for ( idx=0; idx<num_services; idx++ ) {
1268 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1269 print_notify_deregister_pid(idx);
1272 return True;
1274 else /* deregister a specific printer */
1276 printername = lp_const_servicename(snum);
1277 pdb = get_print_db_byname(printername);
1278 if (!pdb)
1279 return False;
1280 tdb = pdb->tdb;
1283 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1284 DEBUG(0,("print_notify_register_pid: Failed to lock \
1285 printer %s database\n", printername));
1286 if (pdb)
1287 release_print_db(pdb);
1288 return False;
1291 data = get_printer_notify_pid_list( tdb, printername, True );
1293 /* Reduce refcount. Remove ourselves if zero. */
1295 for (i = 0; i < data.dsize; ) {
1296 if (IVAL(data.dptr,i) == mypid) {
1297 uint32 refcount = IVAL(data.dptr, i+4);
1299 refcount--;
1301 if (refcount == 0) {
1302 if (data.dsize - i > 8)
1303 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1304 data.dsize -= 8;
1305 continue;
1307 SIVAL(data.dptr, i+4, refcount);
1310 i += 8;
1313 if (data.dsize == 0)
1314 SAFE_FREE(data.dptr);
1316 /* Store back the record. */
1317 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1318 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1319 list for printer %s\n", printername));
1320 goto done;
1323 ret = True;
1325 done:
1327 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1328 if (pdb)
1329 release_print_db(pdb);
1330 SAFE_FREE(data.dptr);
1331 return ret;
1334 /****************************************************************************
1335 Check if a jobid is valid. It is valid if it exists in the database.
1336 ****************************************************************************/
1338 BOOL print_job_exists(int snum, uint32 jobid)
1340 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1341 BOOL ret;
1343 if (!pdb)
1344 return False;
1345 ret = tdb_exists(pdb->tdb, print_key(jobid));
1346 release_print_db(pdb);
1347 return ret;
1350 /****************************************************************************
1351 Give the fd used for a jobid.
1352 ****************************************************************************/
1354 int print_job_fd(int snum, uint32 jobid)
1356 struct printjob *pjob = print_job_find(snum, jobid);
1357 if (!pjob)
1358 return -1;
1359 /* don't allow another process to get this info - it is meaningless */
1360 if (pjob->pid != local_pid)
1361 return -1;
1362 return pjob->fd;
1365 /****************************************************************************
1366 Give the filename used for a jobid.
1367 Only valid for the process doing the spooling and when the job
1368 has not been spooled.
1369 ****************************************************************************/
1371 char *print_job_fname(int snum, uint32 jobid)
1373 struct printjob *pjob = print_job_find(snum, jobid);
1374 if (!pjob || pjob->spooled || pjob->pid != local_pid)
1375 return NULL;
1376 return pjob->filename;
1380 /****************************************************************************
1381 Give the filename used for a jobid.
1382 Only valid for the process doing the spooling and when the job
1383 has not been spooled.
1384 ****************************************************************************/
1386 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1388 struct printjob *pjob = print_job_find(snum, jobid);
1390 if ( !pjob )
1391 return NULL;
1393 return pjob->nt_devmode;
1396 /****************************************************************************
1397 Set the place in the queue for a job.
1398 ****************************************************************************/
1400 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1402 DEBUG(2,("print_job_set_place not implemented yet\n"));
1403 return False;
1406 /****************************************************************************
1407 Set the name of a job. Only possible for owner.
1408 ****************************************************************************/
1410 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1412 struct printjob *pjob = print_job_find(snum, jobid);
1413 if (!pjob || pjob->pid != local_pid)
1414 return False;
1416 fstrcpy(pjob->jobname, name);
1417 return pjob_store(snum, jobid, pjob);
1420 /***************************************************************************
1421 Remove a jobid from the 'jobs changed' list.
1422 ***************************************************************************/
1424 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1426 const char *printername = lp_const_servicename(snum);
1427 struct tdb_print_db *pdb = get_print_db_byname(printername);
1428 TDB_DATA data, key;
1429 size_t job_count, i;
1430 BOOL ret = False;
1431 BOOL gotlock = False;
1433 key.dptr = "INFO/jobs_changed";
1434 key.dsize = strlen(key.dptr);
1435 ZERO_STRUCT(data);
1437 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1438 goto out;
1440 gotlock = True;
1442 data = tdb_fetch(pdb->tdb, key);
1444 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1445 goto out;
1447 job_count = data.dsize / 4;
1448 for (i = 0; i < job_count; i++) {
1449 uint32 ch_jobid;
1451 ch_jobid = IVAL(data.dptr, i*4);
1452 if (ch_jobid == jobid) {
1453 if (i < job_count -1 )
1454 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1455 data.dsize -= 4;
1456 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1457 goto out;
1458 break;
1462 ret = True;
1463 out:
1465 if (gotlock)
1466 tdb_chainunlock(pdb->tdb, key);
1467 SAFE_FREE(data.dptr);
1468 release_print_db(pdb);
1469 if (ret)
1470 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1471 else
1472 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1473 return ret;
1476 /****************************************************************************
1477 Delete a print job - don't update queue.
1478 ****************************************************************************/
1480 static BOOL print_job_delete1(int snum, uint32 jobid)
1482 struct printjob *pjob = print_job_find(snum, jobid);
1483 int result = 0;
1484 struct printif *current_printif = get_printer_fns( snum );
1486 if (!pjob)
1487 return False;
1490 * If already deleting just return.
1493 if (pjob->status == LPQ_DELETING)
1494 return True;
1496 /* Hrm - we need to be able to cope with deleting a job before it
1497 has reached the spooler. */
1499 if (pjob->sysjob == -1) {
1500 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1503 /* Set the tdb entry to be deleting. */
1505 pjob->status = LPQ_DELETING;
1506 pjob_store(snum, jobid, pjob);
1508 if (pjob->spooled && pjob->sysjob != -1)
1509 result = (*(current_printif->job_delete))(snum, pjob);
1510 else
1511 remove_from_jobs_changed(snum, jobid);
1513 /* Delete the tdb entry if the delete succeeded or the job hasn't
1514 been spooled. */
1516 if (result == 0) {
1517 const char *printername = lp_const_servicename(snum);
1518 struct tdb_print_db *pdb = get_print_db_byname(printername);
1519 int njobs = 1;
1521 if (!pdb)
1522 return False;
1523 pjob_delete(snum, jobid);
1524 /* Ensure we keep a rough count of the number of total jobs... */
1525 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1526 release_print_db(pdb);
1529 return (result == 0);
1532 /****************************************************************************
1533 Return true if the current user owns the print job.
1534 ****************************************************************************/
1536 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1538 struct printjob *pjob = print_job_find(snum, jobid);
1539 user_struct *vuser;
1541 if (!pjob || !user)
1542 return False;
1544 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1545 return strequal(pjob->user, vuser->user.smb_name);
1546 } else {
1547 return strequal(pjob->user, uidtoname(user->uid));
1551 /****************************************************************************
1552 Delete a print job.
1553 ****************************************************************************/
1555 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1557 BOOL owner, deleted;
1558 char *fname;
1560 *errcode = WERR_OK;
1562 owner = is_owner(user, snum, jobid);
1564 /* Check access against security descriptor or whether the user
1565 owns their job. */
1567 if (!owner &&
1568 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1569 DEBUG(3, ("delete denied by security descriptor\n"));
1570 *errcode = WERR_ACCESS_DENIED;
1572 /* BEGIN_ADMIN_LOG */
1573 sys_adminlog( LOG_ERR,
1574 "Permission denied-- user not allowed to delete, \
1575 pause, or resume print job. User name: %s. Printer name: %s.",
1576 uidtoname(user->uid), PRINTERNAME(snum) );
1577 /* END_ADMIN_LOG */
1579 return False;
1583 * get the spooled filename of the print job
1584 * if this works, then the file has not been spooled
1585 * to the underlying print system. Just delete the
1586 * spool file & return.
1589 if ( (fname = print_job_fname( snum, jobid )) != NULL )
1591 /* remove the spool file */
1592 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1593 if ( unlink( fname ) == -1 ) {
1594 *errcode = map_werror_from_unix(errno);
1595 return False;
1598 return True;
1601 if (!print_job_delete1(snum, jobid)) {
1602 *errcode = WERR_ACCESS_DENIED;
1603 return False;
1606 /* force update the database and say the delete failed if the
1607 job still exists */
1609 print_queue_update(snum);
1611 deleted = !print_job_exists(snum, jobid);
1612 if ( !deleted )
1613 *errcode = WERR_ACCESS_DENIED;
1615 return deleted;
1618 /****************************************************************************
1619 Pause a job.
1620 ****************************************************************************/
1622 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1624 struct printjob *pjob = print_job_find(snum, jobid);
1625 int ret = -1;
1626 struct printif *current_printif = get_printer_fns( snum );
1628 if (!pjob || !user)
1629 return False;
1631 if (!pjob->spooled || pjob->sysjob == -1)
1632 return False;
1634 if (!is_owner(user, snum, jobid) &&
1635 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1636 DEBUG(3, ("pause denied by security descriptor\n"));
1638 /* BEGIN_ADMIN_LOG */
1639 sys_adminlog( LOG_ERR,
1640 "Permission denied-- user not allowed to delete, \
1641 pause, or resume print job. User name: %s. Printer name: %s.",
1642 uidtoname(user->uid), PRINTERNAME(snum) );
1643 /* END_ADMIN_LOG */
1645 *errcode = WERR_ACCESS_DENIED;
1646 return False;
1649 /* need to pause the spooled entry */
1650 ret = (*(current_printif->job_pause))(snum, pjob);
1652 if (ret != 0) {
1653 *errcode = WERR_INVALID_PARAM;
1654 return False;
1657 /* force update the database */
1658 print_cache_flush(snum);
1660 /* Send a printer notify message */
1662 notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1664 /* how do we tell if this succeeded? */
1666 return True;
1669 /****************************************************************************
1670 Resume a job.
1671 ****************************************************************************/
1673 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1675 struct printjob *pjob = print_job_find(snum, jobid);
1676 int ret;
1677 struct printif *current_printif = get_printer_fns( snum );
1679 if (!pjob || !user)
1680 return False;
1682 if (!pjob->spooled || pjob->sysjob == -1)
1683 return False;
1685 if (!is_owner(user, snum, jobid) &&
1686 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1687 DEBUG(3, ("resume denied by security descriptor\n"));
1688 *errcode = WERR_ACCESS_DENIED;
1690 /* BEGIN_ADMIN_LOG */
1691 sys_adminlog( LOG_ERR,
1692 "Permission denied-- user not allowed to delete, \
1693 pause, or resume print job. User name: %s. Printer name: %s.",
1694 uidtoname(user->uid), PRINTERNAME(snum) );
1695 /* END_ADMIN_LOG */
1696 return False;
1699 ret = (*(current_printif->job_resume))(snum, pjob);
1701 if (ret != 0) {
1702 *errcode = WERR_INVALID_PARAM;
1703 return False;
1706 /* force update the database */
1707 print_cache_flush(snum);
1709 /* Send a printer notify message */
1711 notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1713 return True;
1716 /****************************************************************************
1717 Write to a print file.
1718 ****************************************************************************/
1720 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1722 int return_code;
1723 struct printjob *pjob = print_job_find(snum, jobid);
1725 if (!pjob)
1726 return -1;
1727 /* don't allow another process to get this info - it is meaningless */
1728 if (pjob->pid != local_pid)
1729 return -1;
1731 return_code = write(pjob->fd, buf, size);
1732 if (return_code>0) {
1733 pjob->size += size;
1734 pjob_store(snum, jobid, pjob);
1736 return return_code;
1739 /****************************************************************************
1740 Check if the print queue has been updated recently enough.
1741 ****************************************************************************/
1743 static BOOL print_cache_expired(int snum)
1745 fstring key;
1746 time_t last_qscan_time, time_now = time(NULL);
1747 const char *printername = lp_const_servicename(snum);
1748 struct tdb_print_db *pdb = get_print_db_byname(printername);
1750 if (!pdb)
1751 return False;
1753 slprintf(key, sizeof(key), "CACHE/%s", printername);
1754 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1757 * Invalidate the queue for 3 reasons.
1758 * (1). last queue scan time == -1.
1759 * (2). Current time - last queue scan time > allowed cache time.
1760 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1761 * This last test picks up machines for which the clock has been moved
1762 * forward, an lpq scan done and then the clock moved back. Otherwise
1763 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1766 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1767 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1768 DEBUG(3, ("print cache expired for queue %s \
1769 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1770 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1771 release_print_db(pdb);
1772 return True;
1774 release_print_db(pdb);
1775 return False;
1778 /****************************************************************************
1779 Get the queue status - do not update if db is out of date.
1780 ****************************************************************************/
1782 static int get_queue_status(int snum, print_status_struct *status)
1784 fstring keystr;
1785 TDB_DATA data, key;
1786 const char *printername = lp_const_servicename(snum);
1787 struct tdb_print_db *pdb = get_print_db_byname(printername);
1788 int len;
1790 if (!pdb)
1791 return 0;
1793 if (status) {
1794 ZERO_STRUCTP(status);
1795 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1796 key.dptr = keystr;
1797 key.dsize = strlen(keystr);
1798 data = tdb_fetch(pdb->tdb, key);
1799 if (data.dptr) {
1800 if (data.dsize == sizeof(print_status_struct))
1801 /* this memcpy is ok since the status struct was
1802 not packed before storing it in the tdb */
1803 memcpy(status, data.dptr, sizeof(print_status_struct));
1804 SAFE_FREE(data.dptr);
1807 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1808 release_print_db(pdb);
1809 return (len == -1 ? 0 : len);
1812 /****************************************************************************
1813 Determine the number of jobs in a queue.
1814 ****************************************************************************/
1816 int print_queue_length(int snum, print_status_struct *pstatus)
1818 print_status_struct status;
1819 int len;
1821 /* make sure the database is up to date */
1822 if (print_cache_expired(snum))
1823 print_queue_update(snum);
1825 /* also fetch the queue status */
1826 memset(&status, 0, sizeof(status));
1827 len = get_queue_status(snum, &status);
1829 if (pstatus)
1830 *pstatus = status;
1832 return len;
1835 /***************************************************************************
1836 Allocate a jobid. Hold the lock for as short a time as possible.
1837 ***************************************************************************/
1839 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1841 int i;
1842 uint32 jobid;
1844 *pjobid = (uint32)-1;
1846 for (i = 0; i < 3; i++) {
1847 /* Lock the database - only wait 20 seconds. */
1848 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1849 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1850 return False;
1853 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1854 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1855 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1856 printername ));
1857 return False;
1859 jobid = 0;
1862 jobid = NEXT_JOBID(jobid);
1864 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1865 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1866 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1867 return False;
1870 /* We've finished with the INFO/nextjob lock. */
1871 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1873 if (!print_job_exists(snum, jobid))
1874 break;
1877 if (i > 2) {
1878 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1879 printername ));
1880 /* Probably full... */
1881 errno = ENOSPC;
1882 return False;
1885 /* Store a dummy placeholder. */
1887 TDB_DATA dum;
1888 dum.dptr = NULL;
1889 dum.dsize = 0;
1890 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1891 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1892 jobid ));
1893 return False;
1897 *pjobid = jobid;
1898 return True;
1901 /***************************************************************************
1902 Append a jobid to the 'jobs changed' list.
1903 ***************************************************************************/
1905 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1907 TDB_DATA data, key;
1908 uint32 store_jobid;
1910 key.dptr = "INFO/jobs_changed";
1911 key.dsize = strlen(key.dptr);
1912 SIVAL(&store_jobid, 0, jobid);
1913 data.dptr = (char *)&store_jobid;
1914 data.dsize = 4;
1916 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1918 return (tdb_append(pdb->tdb, key, data) == 0);
1921 /***************************************************************************
1922 Start spooling a job - return the jobid.
1923 ***************************************************************************/
1925 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1927 uint32 jobid;
1928 char *path;
1929 struct printjob pjob;
1930 user_struct *vuser;
1931 const char *printername = lp_const_servicename(snum);
1932 struct tdb_print_db *pdb = get_print_db_byname(printername);
1933 int njobs;
1935 errno = 0;
1937 if (!pdb)
1938 return (uint32)-1;
1940 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1941 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1942 release_print_db(pdb);
1943 return (uint32)-1;
1946 if (!print_time_access_check(snum)) {
1947 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1948 release_print_db(pdb);
1949 return (uint32)-1;
1952 path = lp_pathname(snum);
1954 /* see if we have sufficient disk space */
1955 if (lp_minprintspace(snum)) {
1956 SMB_BIG_UINT dspace, dsize;
1957 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1958 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1959 DEBUG(3, ("print_job_start: disk space check failed.\n"));
1960 release_print_db(pdb);
1961 errno = ENOSPC;
1962 return (uint32)-1;
1966 /* for autoloaded printers, check that the printcap entry still exists */
1967 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1968 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1969 release_print_db(pdb);
1970 errno = ENOENT;
1971 return (uint32)-1;
1974 /* Insure the maximum queue size is not violated */
1975 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1976 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1977 printername, njobs, lp_maxprintjobs(snum) ));
1978 release_print_db(pdb);
1979 errno = ENOSPC;
1980 return (uint32)-1;
1983 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1984 printername, njobs, lp_maxprintjobs(snum) ));
1986 if (!allocate_print_jobid(pdb, snum, printername, &jobid))
1987 goto fail;
1989 /* create the database entry */
1991 ZERO_STRUCT(pjob);
1993 pjob.pid = local_pid;
1994 pjob.sysjob = -1;
1995 pjob.fd = -1;
1996 pjob.starttime = time(NULL);
1997 pjob.status = LPQ_SPOOLING;
1998 pjob.size = 0;
1999 pjob.spooled = False;
2000 pjob.smbjob = True;
2001 pjob.nt_devmode = nt_devmode;
2003 fstrcpy(pjob.jobname, jobname);
2005 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2006 fstrcpy(pjob.user, vuser->user.smb_name);
2007 } else {
2008 fstrcpy(pjob.user, uidtoname(user->uid));
2011 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2013 /* we have a job entry - now create the spool file */
2014 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2015 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2016 pjob.fd = smb_mkstemp(pjob.filename);
2018 if (pjob.fd == -1) {
2019 if (errno == EACCES) {
2020 /* Common setup error, force a report. */
2021 DEBUG(0, ("print_job_start: insufficient permissions \
2022 to open spool file %s.\n", pjob.filename));
2023 } else {
2024 /* Normal case, report at level 3 and above. */
2025 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2026 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2028 goto fail;
2031 pjob_store(snum, jobid, &pjob);
2033 /* Update the 'jobs changed' entry used by print_queue_status. */
2034 add_to_jobs_changed(pdb, jobid);
2036 /* Ensure we keep a rough count of the number of total jobs... */
2037 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2039 release_print_db(pdb);
2041 return jobid;
2043 fail:
2044 if (jobid != -1)
2045 pjob_delete(snum, jobid);
2047 release_print_db(pdb);
2049 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2050 return (uint32)-1;
2053 /****************************************************************************
2054 Update the number of pages spooled to jobid
2055 ****************************************************************************/
2057 void print_job_endpage(int snum, uint32 jobid)
2059 struct printjob *pjob = print_job_find(snum, jobid);
2060 if (!pjob)
2061 return;
2062 /* don't allow another process to get this info - it is meaningless */
2063 if (pjob->pid != local_pid)
2064 return;
2066 pjob->page_count++;
2067 pjob_store(snum, jobid, pjob);
2070 /****************************************************************************
2071 Print a file - called on closing the file. This spools the job.
2072 If normal close is false then we're tearing down the jobs - treat as an
2073 error.
2074 ****************************************************************************/
2076 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2078 struct printjob *pjob = print_job_find(snum, jobid);
2079 int ret;
2080 SMB_STRUCT_STAT sbuf;
2081 struct printif *current_printif = get_printer_fns( snum );
2083 if (!pjob)
2084 return False;
2086 if (pjob->spooled || pjob->pid != local_pid)
2087 return False;
2089 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2090 pjob->size = sbuf.st_size;
2091 close(pjob->fd);
2092 pjob->fd = -1;
2093 } else {
2096 * Not a normal close or we couldn't stat the job file,
2097 * so something has gone wrong. Cleanup.
2099 close(pjob->fd);
2100 pjob->fd = -1;
2101 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2102 goto fail;
2105 /* Technically, this is not quite right. If the printer has a separator
2106 * page turned on, the NT spooler prints the separator page even if the
2107 * print job is 0 bytes. 010215 JRR */
2108 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2109 /* don't bother spooling empty files or something being deleted. */
2110 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2111 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2112 unlink(pjob->filename);
2113 pjob_delete(snum, jobid);
2114 return True;
2117 pjob->smbjob = jobid;
2119 ret = (*(current_printif->job_submit))(snum, pjob);
2121 if (ret)
2122 goto fail;
2124 /* The print job has been sucessfully handed over to the back-end */
2126 pjob->spooled = True;
2127 pjob->status = LPQ_QUEUED;
2128 pjob_store(snum, jobid, pjob);
2130 /* make sure the database is up to date */
2131 if (print_cache_expired(snum))
2132 print_queue_update(snum);
2134 return True;
2136 fail:
2138 /* The print job was not succesfully started. Cleanup */
2139 /* Still need to add proper error return propagation! 010122:JRR */
2140 unlink(pjob->filename);
2141 pjob_delete(snum, jobid);
2142 remove_from_jobs_changed(snum, jobid);
2143 return False;
2146 /****************************************************************************
2147 Get a snapshot of jobs in the system without traversing.
2148 ****************************************************************************/
2150 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2152 TDB_DATA data, key, cgdata;
2153 print_queue_struct *queue = NULL;
2154 uint32 qcount = 0;
2155 uint32 extra_count = 0;
2156 int total_count = 0;
2157 size_t len = 0;
2158 uint32 i;
2159 int max_reported_jobs = lp_max_reported_jobs(snum);
2160 BOOL ret = False;
2162 /* make sure the database is up to date */
2163 if (print_cache_expired(snum))
2164 print_queue_update(snum);
2166 *pcount = 0;
2167 *ppqueue = NULL;
2169 ZERO_STRUCT(data);
2170 ZERO_STRUCT(cgdata);
2171 key.dptr = "INFO/linear_queue_array";
2172 key.dsize = strlen(key.dptr);
2174 /* Get the stored queue data. */
2175 data = tdb_fetch(pdb->tdb, key);
2177 if (data.dptr && data.dsize >= sizeof(qcount))
2178 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2180 /* Get the changed jobs list. */
2181 key.dptr = "INFO/jobs_changed";
2182 key.dsize = strlen(key.dptr);
2184 cgdata = tdb_fetch(pdb->tdb, key);
2185 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2186 extra_count = cgdata.dsize/4;
2188 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2190 /* Allocate the queue size. */
2191 if (qcount == 0 && extra_count == 0)
2192 goto out;
2194 if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2195 goto out;
2197 /* Retrieve the linearised queue data. */
2199 for( i = 0; i < qcount; i++) {
2200 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2201 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2202 &qjob,
2203 &qsize,
2204 &qpage_count,
2205 &qstatus,
2206 &qpriority,
2207 &qtime,
2208 queue[i].fs_user,
2209 queue[i].fs_file);
2210 queue[i].job = qjob;
2211 queue[i].size = qsize;
2212 queue[i].page_count = qpage_count;
2213 queue[i].status = qstatus;
2214 queue[i].priority = qpriority;
2215 queue[i].time = qtime;
2218 total_count = qcount;
2220 /* Add in the changed jobids. */
2221 for( i = 0; i < extra_count; i++) {
2222 uint32 jobid;
2223 struct printjob *pjob;
2225 jobid = IVAL(cgdata.dptr, i*4);
2226 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2227 pjob = print_job_find(snum, jobid);
2228 if (!pjob) {
2229 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2230 remove_from_jobs_changed(snum, jobid);
2231 continue;
2234 queue[total_count].job = jobid;
2235 queue[total_count].size = pjob->size;
2236 queue[total_count].page_count = pjob->page_count;
2237 queue[total_count].status = pjob->status;
2238 queue[total_count].priority = 1;
2239 queue[total_count].time = pjob->starttime;
2240 fstrcpy(queue[total_count].fs_user, pjob->user);
2241 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2242 total_count++;
2245 /* Sort the queue by submission time otherwise they are displayed
2246 in hash order. */
2248 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2250 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2252 if (max_reported_jobs && total_count > max_reported_jobs)
2253 total_count = max_reported_jobs;
2255 *ppqueue = queue;
2256 *pcount = total_count;
2258 ret = True;
2260 out:
2262 SAFE_FREE(data.dptr);
2263 SAFE_FREE(cgdata.dptr);
2264 return ret;
2267 /****************************************************************************
2268 Get a printer queue listing.
2269 set queue = NULL and status = NULL if you just want to update the cache
2270 ****************************************************************************/
2272 int print_queue_status(int snum,
2273 print_queue_struct **ppqueue,
2274 print_status_struct *status)
2276 fstring keystr;
2277 TDB_DATA data, key;
2278 const char *printername;
2279 struct tdb_print_db *pdb;
2280 int count = 0;
2282 /* make sure the database is up to date */
2284 if (print_cache_expired(snum))
2285 print_queue_update(snum);
2287 /* return if we are done */
2288 if ( !ppqueue || !status )
2289 return 0;
2291 *ppqueue = NULL;
2292 printername = lp_const_servicename(snum);
2293 pdb = get_print_db_byname(printername);
2295 if (!pdb)
2296 return 0;
2299 * Fetch the queue status. We must do this first, as there may
2300 * be no jobs in the queue.
2303 ZERO_STRUCTP(status);
2304 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2305 key.dptr = keystr;
2306 key.dsize = strlen(keystr);
2307 data = tdb_fetch(pdb->tdb, key);
2308 if (data.dptr) {
2309 if (data.dsize == sizeof(*status)) {
2310 /* this memcpy is ok since the status struct was
2311 not packed before storing it in the tdb */
2312 memcpy(status, data.dptr, sizeof(*status));
2314 SAFE_FREE(data.dptr);
2318 * Now, fetch the print queue information. We first count the number
2319 * of entries, and then only retrieve the queue if necessary.
2322 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2323 release_print_db(pdb);
2324 return 0;
2327 release_print_db(pdb);
2328 return count;
2331 /****************************************************************************
2332 Pause a queue.
2333 ****************************************************************************/
2335 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2337 int ret;
2338 struct printif *current_printif = get_printer_fns( snum );
2340 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2341 *errcode = WERR_ACCESS_DENIED;
2342 return False;
2345 ret = (*(current_printif->queue_pause))(snum);
2347 if (ret != 0) {
2348 *errcode = WERR_INVALID_PARAM;
2349 return False;
2352 /* force update the database */
2353 print_cache_flush(snum);
2355 /* Send a printer notify message */
2357 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2359 return True;
2362 /****************************************************************************
2363 Resume a queue.
2364 ****************************************************************************/
2366 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2368 int ret;
2369 struct printif *current_printif = get_printer_fns( snum );
2371 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2372 *errcode = WERR_ACCESS_DENIED;
2373 return False;
2376 ret = (*(current_printif->queue_resume))(snum);
2378 if (ret != 0) {
2379 *errcode = WERR_INVALID_PARAM;
2380 return False;
2383 /* make sure the database is up to date */
2384 if (print_cache_expired(snum))
2385 print_queue_update(snum);
2387 /* Send a printer notify message */
2389 notify_printer_status(snum, PRINTER_STATUS_OK);
2391 return True;
2394 /****************************************************************************
2395 Purge a queue - implemented by deleting all jobs that we can delete.
2396 ****************************************************************************/
2398 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2400 print_queue_struct *queue;
2401 print_status_struct status;
2402 int njobs, i;
2403 BOOL can_job_admin;
2405 /* Force and update so the count is accurate (i.e. not a cached count) */
2406 print_queue_update(snum);
2408 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2409 njobs = print_queue_status(snum, &queue, &status);
2411 for (i=0;i<njobs;i++) {
2412 BOOL owner = is_owner(user, snum, queue[i].job);
2414 if (owner || can_job_admin) {
2415 print_job_delete1(snum, queue[i].job);
2419 SAFE_FREE(queue);
2421 return True;