fix byte ordering problem when storing the updating pid for the lpq cache; was causin...
[Samba/bb.git] / source / printing / printing.c
blobed19c01f2439e57efc8cca24cb65b8cc6123d8b4
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 j = 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 = (uint32 *)key.dptr;
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 && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) )
538 pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob );
540 done:
541 SAFE_FREE( old_data.dptr );
542 SAFE_FREE( buf );
544 return ret;
547 /****************************************************************************
548 Remove a job structure from the database.
549 ****************************************************************************/
551 void pjob_delete(int snum, uint32 jobid)
553 struct printjob *pjob = print_job_find(snum, jobid);
554 uint32 job_status = 0;
555 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
557 if (!pdb)
558 return;
560 if (!pjob) {
561 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
562 (unsigned int)jobid));
563 release_print_db(pdb);
564 return;
567 /* Send a notification that a job has been deleted */
569 job_status = map_to_spoolss_status(pjob->status);
571 /* We must cycle through JOB_STATUS_DELETING and
572 JOB_STATUS_DELETED for the port monitor to delete the job
573 properly. */
575 job_status |= JOB_STATUS_DELETING;
576 notify_job_status(snum, jobid, job_status);
578 job_status |= JOB_STATUS_DELETED;
579 notify_job_status(snum, jobid, job_status);
581 /* Remove from printing.tdb */
583 tdb_delete(pdb->tdb, print_key(jobid));
584 release_print_db(pdb);
585 rap_jobid_delete(snum, jobid);
588 /****************************************************************************
589 Parse a file name from the system spooler to generate a jobid.
590 ****************************************************************************/
592 static uint32 print_parse_jobid(char *fname)
594 int jobid;
596 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
597 return (uint32)-1;
598 fname += strlen(PRINT_SPOOL_PREFIX);
600 jobid = atoi(fname);
601 if (jobid <= 0)
602 return (uint32)-1;
604 return (uint32)jobid;
607 /****************************************************************************
608 List a unix job in the print database.
609 ****************************************************************************/
611 static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
613 struct printjob pj, *old_pj;
615 if (jobid == (uint32)-1)
616 jobid = q->job + UNIX_JOB_START;
618 /* Preserve the timestamp on an existing unix print job */
620 old_pj = print_job_find(snum, jobid);
622 ZERO_STRUCT(pj);
624 pj.pid = (pid_t)-1;
625 pj.sysjob = q->job;
626 pj.fd = -1;
627 pj.starttime = old_pj ? old_pj->starttime : q->time;
628 pj.status = q->status;
629 pj.size = q->size;
630 pj.spooled = True;
631 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
632 if (jobid < UNIX_JOB_START) {
633 pj.smbjob = True;
634 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
635 } else {
636 pj.smbjob = False;
637 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
639 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
640 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
642 pjob_store(snum, jobid, &pj);
646 struct traverse_struct {
647 print_queue_struct *queue;
648 int qcount, snum, maxcount, total_jobs;
649 time_t lpq_time;
652 /****************************************************************************
653 Utility fn to delete any jobs that are no longer active.
654 ****************************************************************************/
656 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
658 struct traverse_struct *ts = (struct traverse_struct *)state;
659 struct printjob pjob;
660 uint32 jobid;
661 int i = 0;
663 if ( key.dsize != sizeof(jobid) )
664 return 0;
666 jobid = IVAL(key.dptr, 0);
667 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
668 return 0;
669 free_nt_devicemode( &pjob.nt_devmode );
672 if (ts->snum != lp_servicenumber(pjob.queuename)) {
673 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
674 return 0;
677 if (!pjob.smbjob) {
678 /* remove a unix job if it isn't in the system queue any more */
680 for (i=0;i<ts->qcount;i++) {
681 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
682 if (jobid == u_jobid)
683 break;
685 if (i == ts->qcount) {
686 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
687 (unsigned int)jobid ));
688 pjob_delete(ts->snum, jobid);
689 return 0;
692 /* need to continue the the bottom of the function to
693 save the correct attributes */
696 /* maybe it hasn't been spooled yet */
697 if (!pjob.spooled) {
698 /* if a job is not spooled and the process doesn't
699 exist then kill it. This cleans up after smbd
700 deaths */
701 if (!process_exists(pjob.pid)) {
702 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
703 (unsigned int)jobid, (unsigned int)pjob.pid ));
704 pjob_delete(ts->snum, jobid);
705 } else
706 ts->total_jobs++;
707 return 0;
710 /* this check only makes sense for jobs submitted from Windows clients */
712 if ( pjob.smbjob ) {
713 for (i=0;i<ts->qcount;i++) {
714 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
715 if (jobid == curr_jobid)
716 break;
720 /* The job isn't in the system queue - we have to assume it has
721 completed, so delete the database entry. */
723 if (i == ts->qcount) {
725 /* A race can occur between the time a job is spooled and
726 when it appears in the lpq output. This happens when
727 the job is added to printing.tdb when another smbd
728 running print_queue_update() has completed a lpq and
729 is currently traversing the printing tdb and deleting jobs.
730 Don't delete the job if it was submitted after the lpq_time. */
732 if (pjob.starttime < ts->lpq_time) {
733 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
734 (unsigned int)jobid,
735 (unsigned int)pjob.starttime,
736 (unsigned int)ts->lpq_time ));
737 pjob_delete(ts->snum, jobid);
738 } else
739 ts->total_jobs++;
740 return 0;
743 /* Save the pjob attributes we will store. */
744 /* FIXME!!! This is the only place where queue->job
745 represents the SMB jobid --jerry */
746 ts->queue[i].job = jobid;
747 ts->queue[i].size = pjob.size;
748 ts->queue[i].page_count = pjob.page_count;
749 ts->queue[i].status = pjob.status;
750 ts->queue[i].priority = 1;
751 ts->queue[i].time = pjob.starttime;
752 fstrcpy(ts->queue[i].fs_user, pjob.user);
753 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
755 ts->total_jobs++;
757 return 0;
760 /****************************************************************************
761 Check if the print queue has been updated recently enough.
762 ****************************************************************************/
764 static void print_cache_flush(int snum)
766 fstring key;
767 const char *printername = lp_const_servicename(snum);
768 struct tdb_print_db *pdb = get_print_db_byname(printername);
770 if (!pdb)
771 return;
772 slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
773 tdb_store_int32(pdb->tdb, key, -1);
774 release_print_db(pdb);
777 /****************************************************************************
778 Check if someone already thinks they are doing the update.
779 ****************************************************************************/
781 static pid_t get_updating_pid(fstring printer_name)
783 fstring keystr;
784 TDB_DATA data, key;
785 pid_t updating_pid;
786 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
788 if (!pdb)
789 return (pid_t)-1;
790 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
791 key.dptr = keystr;
792 key.dsize = strlen(keystr);
794 data = tdb_fetch(pdb->tdb, key);
795 release_print_db(pdb);
796 if (!data.dptr || data.dsize != sizeof(pid_t)) {
797 SAFE_FREE(data.dptr);
798 return (pid_t)-1;
801 updating_pid = IVAL(data.dptr, 0);
802 SAFE_FREE(data.dptr);
804 if (process_exists(updating_pid))
805 return updating_pid;
807 return (pid_t)-1;
810 /****************************************************************************
811 Set the fact that we're doing the update, or have finished doing the update
812 in the tdb.
813 ****************************************************************************/
815 static void set_updating_pid(const fstring printer_name, BOOL delete)
817 fstring keystr;
818 TDB_DATA key;
819 TDB_DATA data;
820 pid_t updating_pid = sys_getpid();
821 uint8 buffer[4];
823 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
825 if (!pdb)
826 return;
828 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
829 key.dptr = keystr;
830 key.dsize = strlen(keystr);
832 if (delete) {
833 tdb_delete(pdb->tdb, key);
834 release_print_db(pdb);
835 return;
838 SIVAL( buffer, 0, updating_pid);
839 data.dptr = (void *)buffer;
840 data.dsize = 4; /* we always assume this is a 4 byte value */
842 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
843 release_print_db(pdb);
846 /****************************************************************************
847 Sort print jobs by submittal time.
848 ****************************************************************************/
850 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
852 /* Silly cases */
854 if (!j1 && !j2)
855 return 0;
856 if (!j1)
857 return -1;
858 if (!j2)
859 return 1;
861 /* Sort on job start time */
863 if (j1->time == j2->time)
864 return 0;
865 return (j1->time > j2->time) ? 1 : -1;
868 /****************************************************************************
869 Store the sorted queue representation for later portmon retrieval.
870 ****************************************************************************/
872 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
874 TDB_DATA data, key;
875 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
876 print_queue_struct *queue = pts->queue;
877 size_t len;
878 size_t i;
879 uint qcount;
881 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
882 pts->qcount = max_reported_jobs;
883 qcount = pts->qcount;
885 /* Work out the size. */
886 data.dsize = 0;
887 data.dsize += tdb_pack(NULL, 0, "d", qcount);
889 for (i = 0; i < pts->qcount; i++) {
890 data.dsize += tdb_pack(NULL, 0, "ddddddff",
891 (uint32)queue[i].job,
892 (uint32)queue[i].size,
893 (uint32)queue[i].page_count,
894 (uint32)queue[i].status,
895 (uint32)queue[i].priority,
896 (uint32)queue[i].time,
897 queue[i].fs_user,
898 queue[i].fs_file);
901 if ((data.dptr = malloc(data.dsize)) == NULL)
902 return;
904 len = 0;
905 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
906 for (i = 0; i < pts->qcount; i++) {
907 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
908 (uint32)queue[i].job,
909 (uint32)queue[i].size,
910 (uint32)queue[i].page_count,
911 (uint32)queue[i].status,
912 (uint32)queue[i].priority,
913 (uint32)queue[i].time,
914 queue[i].fs_user,
915 queue[i].fs_file);
918 key.dptr = "INFO/linear_queue_array";
919 key.dsize = strlen(key.dptr);
920 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
921 SAFE_FREE(data.dptr);
922 return;
925 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
927 TDB_DATA data, key;
929 key.dptr = "INFO/jobs_changed";
930 key.dsize = strlen(key.dptr);
931 ZERO_STRUCT(data);
933 data = tdb_fetch(pdb->tdb, key);
934 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
935 SAFE_FREE(data.dptr);
936 ZERO_STRUCT(data);
939 return data;
942 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
944 unsigned int i;
945 unsigned int job_count = data.dsize / 4;
947 for (i = 0; i < job_count; i++) {
948 uint32 ch_jobid;
950 ch_jobid = IVAL(data.dptr, i*4);
951 if (ch_jobid == jobid)
952 remove_from_jobs_changed(snum, jobid);
956 /****************************************************************************
957 Update the internal database from the system print queue for a queue.
958 ****************************************************************************/
960 static void print_queue_update(int snum)
962 int i, qcount;
963 print_queue_struct *queue = NULL;
964 print_status_struct status;
965 print_status_struct old_status;
966 struct printjob *pjob;
967 struct traverse_struct tstruct;
968 fstring keystr, printer_name, cachestr;
969 TDB_DATA data, key;
970 TDB_DATA jcdata;
971 struct tdb_print_db *pdb;
972 struct printif *current_printif = get_printer_fns( snum );
974 fstrcpy(printer_name, lp_const_servicename(snum));
975 pdb = get_print_db_byname(printer_name);
976 if (!pdb)
977 return;
980 * Check to see if someone else is doing this update.
981 * This is essentially a mutex on the update.
984 if (get_updating_pid(printer_name) != -1) {
985 release_print_db(pdb);
986 return;
989 /* Lock the queue for the database update */
991 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
992 /* Only wait 10 seconds for this. */
993 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
994 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
995 release_print_db(pdb);
996 return;
1000 * Ensure that no one else got in here.
1001 * If the updating pid is still -1 then we are
1002 * the winner.
1005 if (get_updating_pid(printer_name) != -1) {
1007 * Someone else is doing the update, exit.
1009 tdb_unlock_bystring(pdb->tdb, keystr);
1010 release_print_db(pdb);
1011 return;
1015 * We're going to do the update ourselves.
1018 /* Tell others we're doing the update. */
1019 set_updating_pid(printer_name, False);
1022 * Allow others to enter and notice we're doing
1023 * the update.
1026 tdb_unlock_bystring(pdb->tdb, keystr);
1029 * Update the cache time FIRST ! Stops others even
1030 * attempting to get the lock and doing this
1031 * if the lpq takes a long time.
1034 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
1035 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1037 /* get the current queue using the appropriate interface */
1038 ZERO_STRUCT(status);
1040 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
1042 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1043 "s" : "", printer_name));
1045 /* Sort the queue by submission time otherwise they are displayed
1046 in hash order. */
1048 qsort(queue, qcount, sizeof(print_queue_struct),
1049 QSORT_CAST(printjob_comp));
1052 any job in the internal database that is marked as spooled
1053 and doesn't exist in the system queue is considered finished
1054 and removed from the database
1056 any job in the system database but not in the internal database
1057 is added as a unix job
1059 fill in any system job numbers as we go
1062 jcdata = get_jobs_changed_data(pdb);
1064 for (i=0; i<qcount; i++) {
1065 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1067 if (jobid == (uint32)-1) {
1068 /* assume its a unix print job */
1069 print_unix_job(snum, &queue[i], jobid);
1070 continue;
1073 /* we have an active SMB print job - update its status */
1074 pjob = print_job_find(snum, jobid);
1075 if (!pjob) {
1076 /* err, somethings wrong. Probably smbd was restarted
1077 with jobs in the queue. All we can do is treat them
1078 like unix jobs. Pity. */
1079 print_unix_job(snum, &queue[i], jobid);
1080 continue;
1083 pjob->sysjob = queue[i].job;
1084 pjob->status = queue[i].status;
1085 pjob_store(snum, jobid, pjob);
1086 check_job_changed(snum, jcdata, jobid);
1089 SAFE_FREE(jcdata.dptr);
1091 /* now delete any queued entries that don't appear in the
1092 system queue */
1093 tstruct.queue = queue;
1094 tstruct.qcount = qcount;
1095 tstruct.snum = snum;
1096 tstruct.total_jobs = 0;
1097 tstruct.lpq_time = time(NULL);
1099 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1101 /* Store the linearised queue, max jobs only. */
1102 store_queue_struct(pdb, &tstruct);
1104 SAFE_FREE(tstruct.queue);
1106 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1107 printer_name, tstruct.total_jobs ));
1109 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1111 get_queue_status(snum, &old_status);
1112 if (old_status.qcount != qcount)
1113 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1114 old_status.qcount, qcount, printer_name ));
1116 /* store the new queue status structure */
1117 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1118 key.dptr = keystr;
1119 key.dsize = strlen(keystr);
1121 status.qcount = qcount;
1122 data.dptr = (void *)&status;
1123 data.dsize = sizeof(status);
1124 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1127 * Update the cache time again. We want to do this call
1128 * as little as possible...
1131 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1132 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1134 /* Delete our pid from the db. */
1135 set_updating_pid(printer_name, True);
1136 release_print_db(pdb);
1139 /****************************************************************************
1140 Create/Update an entry in the print tdb that will allow us to send notify
1141 updates only to interested smbd's.
1142 ****************************************************************************/
1144 BOOL print_notify_register_pid(int snum)
1146 TDB_DATA data;
1147 struct tdb_print_db *pdb = NULL;
1148 TDB_CONTEXT *tdb = NULL;
1149 const char *printername;
1150 uint32 mypid = (uint32)sys_getpid();
1151 BOOL ret = False;
1152 size_t i;
1154 /* if (snum == -1), then the change notify request was
1155 on a print server handle and we need to register on
1156 all print queus */
1158 if (snum == -1)
1160 int num_services = lp_numservices();
1161 int idx;
1163 for ( idx=0; idx<num_services; idx++ ) {
1164 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1165 print_notify_register_pid(idx);
1168 return True;
1170 else /* register for a specific printer */
1172 printername = lp_const_servicename(snum);
1173 pdb = get_print_db_byname(printername);
1174 if (!pdb)
1175 return False;
1176 tdb = pdb->tdb;
1179 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1180 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1181 printername));
1182 if (pdb)
1183 release_print_db(pdb);
1184 return False;
1187 data = get_printer_notify_pid_list( tdb, printername, True );
1189 /* Add ourselves and increase the refcount. */
1191 for (i = 0; i < data.dsize; i += 8) {
1192 if (IVAL(data.dptr,i) == mypid) {
1193 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1194 SIVAL(data.dptr, i+4, new_refcount);
1195 break;
1199 if (i == data.dsize) {
1200 /* We weren't in the list. Realloc. */
1201 data.dptr = Realloc(data.dptr, data.dsize + 8);
1202 if (!data.dptr) {
1203 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1204 printername));
1205 goto done;
1207 data.dsize += 8;
1208 SIVAL(data.dptr,data.dsize - 8,mypid);
1209 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1212 /* Store back the record. */
1213 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1214 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1215 list for printer %s\n", printername));
1216 goto done;
1219 ret = True;
1221 done:
1223 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1224 if (pdb)
1225 release_print_db(pdb);
1226 SAFE_FREE(data.dptr);
1227 return ret;
1230 /****************************************************************************
1231 Update an entry in the print tdb that will allow us to send notify
1232 updates only to interested smbd's.
1233 ****************************************************************************/
1235 BOOL print_notify_deregister_pid(int snum)
1237 TDB_DATA data;
1238 struct tdb_print_db *pdb = NULL;
1239 TDB_CONTEXT *tdb = NULL;
1240 const char *printername;
1241 uint32 mypid = (uint32)sys_getpid();
1242 size_t i;
1243 BOOL ret = False;
1245 /* if ( snum == -1 ), we are deregister a print server handle
1246 which means to deregister on all print queues */
1248 if (snum == -1)
1250 int num_services = lp_numservices();
1251 int idx;
1253 for ( idx=0; idx<num_services; idx++ ) {
1254 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1255 print_notify_deregister_pid(idx);
1258 return True;
1260 else /* deregister a specific printer */
1262 printername = lp_const_servicename(snum);
1263 pdb = get_print_db_byname(printername);
1264 if (!pdb)
1265 return False;
1266 tdb = pdb->tdb;
1269 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1270 DEBUG(0,("print_notify_register_pid: Failed to lock \
1271 printer %s database\n", printername));
1272 if (pdb)
1273 release_print_db(pdb);
1274 return False;
1277 data = get_printer_notify_pid_list( tdb, printername, True );
1279 /* Reduce refcount. Remove ourselves if zero. */
1281 for (i = 0; i < data.dsize; ) {
1282 if (IVAL(data.dptr,i) == mypid) {
1283 uint32 refcount = IVAL(data.dptr, i+4);
1285 refcount--;
1287 if (refcount == 0) {
1288 if (data.dsize - i > 8)
1289 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1290 data.dsize -= 8;
1291 continue;
1293 SIVAL(data.dptr, i+4, refcount);
1296 i += 8;
1299 if (data.dsize == 0)
1300 SAFE_FREE(data.dptr);
1302 /* Store back the record. */
1303 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1304 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1305 list for printer %s\n", printername));
1306 goto done;
1309 ret = True;
1311 done:
1313 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1314 if (pdb)
1315 release_print_db(pdb);
1316 SAFE_FREE(data.dptr);
1317 return ret;
1320 /****************************************************************************
1321 Check if a jobid is valid. It is valid if it exists in the database.
1322 ****************************************************************************/
1324 BOOL print_job_exists(int snum, uint32 jobid)
1326 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1327 BOOL ret;
1329 if (!pdb)
1330 return False;
1331 ret = tdb_exists(pdb->tdb, print_key(jobid));
1332 release_print_db(pdb);
1333 return ret;
1336 /****************************************************************************
1337 Give the fd used for a jobid.
1338 ****************************************************************************/
1340 int print_job_fd(int snum, uint32 jobid)
1342 struct printjob *pjob = print_job_find(snum, jobid);
1343 if (!pjob)
1344 return -1;
1345 /* don't allow another process to get this info - it is meaningless */
1346 if (pjob->pid != local_pid)
1347 return -1;
1348 return pjob->fd;
1351 /****************************************************************************
1352 Give the filename used for a jobid.
1353 Only valid for the process doing the spooling and when the job
1354 has not been spooled.
1355 ****************************************************************************/
1357 char *print_job_fname(int snum, uint32 jobid)
1359 struct printjob *pjob = print_job_find(snum, jobid);
1360 if (!pjob || pjob->spooled || pjob->pid != local_pid)
1361 return NULL;
1362 return pjob->filename;
1366 /****************************************************************************
1367 Give the filename used for a jobid.
1368 Only valid for the process doing the spooling and when the job
1369 has not been spooled.
1370 ****************************************************************************/
1372 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1374 struct printjob *pjob = print_job_find(snum, jobid);
1376 if ( !pjob )
1377 return NULL;
1379 return pjob->nt_devmode;
1382 /****************************************************************************
1383 Set the place in the queue for a job.
1384 ****************************************************************************/
1386 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1388 DEBUG(2,("print_job_set_place not implemented yet\n"));
1389 return False;
1392 /****************************************************************************
1393 Set the name of a job. Only possible for owner.
1394 ****************************************************************************/
1396 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1398 struct printjob *pjob = print_job_find(snum, jobid);
1399 if (!pjob || pjob->pid != local_pid)
1400 return False;
1402 fstrcpy(pjob->jobname, name);
1403 return pjob_store(snum, jobid, pjob);
1406 /***************************************************************************
1407 Remove a jobid from the 'jobs changed' list.
1408 ***************************************************************************/
1410 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1412 const char *printername = lp_const_servicename(snum);
1413 struct tdb_print_db *pdb = get_print_db_byname(printername);
1414 TDB_DATA data, key;
1415 size_t job_count, i;
1416 BOOL ret = False;
1417 BOOL gotlock = False;
1419 key.dptr = "INFO/jobs_changed";
1420 key.dsize = strlen(key.dptr);
1421 ZERO_STRUCT(data);
1423 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1424 goto out;
1426 gotlock = True;
1428 data = tdb_fetch(pdb->tdb, key);
1430 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1431 goto out;
1433 job_count = data.dsize / 4;
1434 for (i = 0; i < job_count; i++) {
1435 uint32 ch_jobid;
1437 ch_jobid = IVAL(data.dptr, i*4);
1438 if (ch_jobid == jobid) {
1439 if (i < job_count -1 )
1440 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1441 data.dsize -= 4;
1442 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1443 goto out;
1444 break;
1448 ret = True;
1449 out:
1451 if (gotlock)
1452 tdb_chainunlock(pdb->tdb, key);
1453 SAFE_FREE(data.dptr);
1454 release_print_db(pdb);
1455 if (ret)
1456 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1457 else
1458 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1459 return ret;
1462 /****************************************************************************
1463 Delete a print job - don't update queue.
1464 ****************************************************************************/
1466 static BOOL print_job_delete1(int snum, uint32 jobid)
1468 struct printjob *pjob = print_job_find(snum, jobid);
1469 int result = 0;
1470 struct printif *current_printif = get_printer_fns( snum );
1472 if (!pjob)
1473 return False;
1476 * If already deleting just return.
1479 if (pjob->status == LPQ_DELETING)
1480 return True;
1482 /* Hrm - we need to be able to cope with deleting a job before it
1483 has reached the spooler. */
1485 if (pjob->sysjob == -1) {
1486 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1489 /* Set the tdb entry to be deleting. */
1491 pjob->status = LPQ_DELETING;
1492 pjob_store(snum, jobid, pjob);
1494 if (pjob->spooled && pjob->sysjob != -1)
1495 result = (*(current_printif->job_delete))(snum, pjob);
1496 else
1497 remove_from_jobs_changed(snum, jobid);
1499 /* Delete the tdb entry if the delete succeeded or the job hasn't
1500 been spooled. */
1502 if (result == 0) {
1503 const char *printername = lp_const_servicename(snum);
1504 struct tdb_print_db *pdb = get_print_db_byname(printername);
1505 int njobs = 1;
1507 if (!pdb)
1508 return False;
1509 pjob_delete(snum, jobid);
1510 /* Ensure we keep a rough count of the number of total jobs... */
1511 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1512 release_print_db(pdb);
1515 return (result == 0);
1518 /****************************************************************************
1519 Return true if the current user owns the print job.
1520 ****************************************************************************/
1522 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1524 struct printjob *pjob = print_job_find(snum, jobid);
1525 user_struct *vuser;
1527 if (!pjob || !user)
1528 return False;
1530 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1531 return strequal(pjob->user, vuser->user.smb_name);
1532 } else {
1533 return strequal(pjob->user, uidtoname(user->uid));
1537 /****************************************************************************
1538 Delete a print job.
1539 ****************************************************************************/
1541 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1543 BOOL owner, deleted;
1544 char *fname;
1546 *errcode = WERR_OK;
1548 owner = is_owner(user, snum, jobid);
1550 /* Check access against security descriptor or whether the user
1551 owns their job. */
1553 if (!owner &&
1554 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1555 DEBUG(3, ("delete denied by security descriptor\n"));
1556 *errcode = WERR_ACCESS_DENIED;
1558 /* BEGIN_ADMIN_LOG */
1559 sys_adminlog( LOG_ERR,
1560 "Permission denied-- user not allowed to delete, \
1561 pause, or resume print job. User name: %s. Printer name: %s.",
1562 uidtoname(user->uid), PRINTERNAME(snum) );
1563 /* END_ADMIN_LOG */
1565 return False;
1569 * get the spooled filename of the print job
1570 * if this works, then the file has not been spooled
1571 * to the underlying print system. Just delete the
1572 * spool file & return.
1575 if ( (fname = print_job_fname( snum, jobid )) != NULL )
1577 /* remove the spool file */
1578 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1579 if ( unlink( fname ) == -1 ) {
1580 *errcode = map_werror_from_unix(errno);
1581 return False;
1584 return True;
1587 if (!print_job_delete1(snum, jobid)) {
1588 *errcode = WERR_ACCESS_DENIED;
1589 return False;
1592 /* force update the database and say the delete failed if the
1593 job still exists */
1595 print_queue_update(snum);
1597 deleted = !print_job_exists(snum, jobid);
1598 if ( !deleted )
1599 *errcode = WERR_ACCESS_DENIED;
1601 return deleted;
1604 /****************************************************************************
1605 Pause a job.
1606 ****************************************************************************/
1608 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1610 struct printjob *pjob = print_job_find(snum, jobid);
1611 int ret = -1;
1612 struct printif *current_printif = get_printer_fns( snum );
1614 if (!pjob || !user)
1615 return False;
1617 if (!pjob->spooled || pjob->sysjob == -1)
1618 return False;
1620 if (!is_owner(user, snum, jobid) &&
1621 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1622 DEBUG(3, ("pause denied by security descriptor\n"));
1624 /* BEGIN_ADMIN_LOG */
1625 sys_adminlog( LOG_ERR,
1626 "Permission denied-- user not allowed to delete, \
1627 pause, or resume print job. User name: %s. Printer name: %s.",
1628 uidtoname(user->uid), PRINTERNAME(snum) );
1629 /* END_ADMIN_LOG */
1631 *errcode = WERR_ACCESS_DENIED;
1632 return False;
1635 /* need to pause the spooled entry */
1636 ret = (*(current_printif->job_pause))(snum, pjob);
1638 if (ret != 0) {
1639 *errcode = WERR_INVALID_PARAM;
1640 return False;
1643 /* force update the database */
1644 print_cache_flush(snum);
1646 /* Send a printer notify message */
1648 notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1650 /* how do we tell if this succeeded? */
1652 return True;
1655 /****************************************************************************
1656 Resume a job.
1657 ****************************************************************************/
1659 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1661 struct printjob *pjob = print_job_find(snum, jobid);
1662 int ret;
1663 struct printif *current_printif = get_printer_fns( snum );
1665 if (!pjob || !user)
1666 return False;
1668 if (!pjob->spooled || pjob->sysjob == -1)
1669 return False;
1671 if (!is_owner(user, snum, jobid) &&
1672 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1673 DEBUG(3, ("resume denied by security descriptor\n"));
1674 *errcode = WERR_ACCESS_DENIED;
1676 /* BEGIN_ADMIN_LOG */
1677 sys_adminlog( LOG_ERR,
1678 "Permission denied-- user not allowed to delete, \
1679 pause, or resume print job. User name: %s. Printer name: %s.",
1680 uidtoname(user->uid), PRINTERNAME(snum) );
1681 /* END_ADMIN_LOG */
1682 return False;
1685 ret = (*(current_printif->job_resume))(snum, pjob);
1687 if (ret != 0) {
1688 *errcode = WERR_INVALID_PARAM;
1689 return False;
1692 /* force update the database */
1693 print_cache_flush(snum);
1695 /* Send a printer notify message */
1697 notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1699 return True;
1702 /****************************************************************************
1703 Write to a print file.
1704 ****************************************************************************/
1706 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1708 int return_code;
1709 struct printjob *pjob = print_job_find(snum, jobid);
1711 if (!pjob)
1712 return -1;
1713 /* don't allow another process to get this info - it is meaningless */
1714 if (pjob->pid != local_pid)
1715 return -1;
1717 return_code = write(pjob->fd, buf, size);
1718 if (return_code>0) {
1719 pjob->size += size;
1720 pjob_store(snum, jobid, pjob);
1722 return return_code;
1725 /****************************************************************************
1726 Check if the print queue has been updated recently enough.
1727 ****************************************************************************/
1729 static BOOL print_cache_expired(int snum)
1731 fstring key;
1732 time_t last_qscan_time, time_now = time(NULL);
1733 const char *printername = lp_const_servicename(snum);
1734 struct tdb_print_db *pdb = get_print_db_byname(printername);
1736 if (!pdb)
1737 return False;
1739 slprintf(key, sizeof(key), "CACHE/%s", printername);
1740 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1743 * Invalidate the queue for 3 reasons.
1744 * (1). last queue scan time == -1.
1745 * (2). Current time - last queue scan time > allowed cache time.
1746 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1747 * This last test picks up machines for which the clock has been moved
1748 * forward, an lpq scan done and then the clock moved back. Otherwise
1749 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1752 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1753 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1754 DEBUG(3, ("print cache expired for queue %s \
1755 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1756 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1757 release_print_db(pdb);
1758 return True;
1760 release_print_db(pdb);
1761 return False;
1764 /****************************************************************************
1765 Get the queue status - do not update if db is out of date.
1766 ****************************************************************************/
1768 static int get_queue_status(int snum, print_status_struct *status)
1770 fstring keystr;
1771 TDB_DATA data, key;
1772 const char *printername = lp_const_servicename(snum);
1773 struct tdb_print_db *pdb = get_print_db_byname(printername);
1774 int len;
1776 if (!pdb)
1777 return 0;
1779 if (status) {
1780 ZERO_STRUCTP(status);
1781 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1782 key.dptr = keystr;
1783 key.dsize = strlen(keystr);
1784 data = tdb_fetch(pdb->tdb, key);
1785 if (data.dptr) {
1786 if (data.dsize == sizeof(print_status_struct))
1787 /* this memcpy is ok since the status struct was
1788 not packed before storing it in the tdb */
1789 memcpy(status, data.dptr, sizeof(print_status_struct));
1790 SAFE_FREE(data.dptr);
1793 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1794 release_print_db(pdb);
1795 return (len == -1 ? 0 : len);
1798 /****************************************************************************
1799 Determine the number of jobs in a queue.
1800 ****************************************************************************/
1802 int print_queue_length(int snum, print_status_struct *pstatus)
1804 print_status_struct status;
1805 int len;
1807 /* make sure the database is up to date */
1808 if (print_cache_expired(snum))
1809 print_queue_update(snum);
1811 /* also fetch the queue status */
1812 memset(&status, 0, sizeof(status));
1813 len = get_queue_status(snum, &status);
1815 if (pstatus)
1816 *pstatus = status;
1818 return len;
1821 /***************************************************************************
1822 Allocate a jobid. Hold the lock for as short a time as possible.
1823 ***************************************************************************/
1825 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1827 int i;
1828 uint32 jobid;
1830 *pjobid = (uint32)-1;
1832 for (i = 0; i < 3; i++) {
1833 /* Lock the database - only wait 20 seconds. */
1834 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1835 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1836 return False;
1839 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1840 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1841 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1842 printername ));
1843 return False;
1845 jobid = 0;
1848 jobid = NEXT_JOBID(jobid);
1850 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1851 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1852 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1853 return False;
1856 /* We've finished with the INFO/nextjob lock. */
1857 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1859 if (!print_job_exists(snum, jobid))
1860 break;
1863 if (i > 2) {
1864 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1865 printername ));
1866 /* Probably full... */
1867 errno = ENOSPC;
1868 return False;
1871 /* Store a dummy placeholder. */
1873 TDB_DATA dum;
1874 dum.dptr = NULL;
1875 dum.dsize = 0;
1876 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1877 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1878 jobid ));
1879 return False;
1883 *pjobid = jobid;
1884 return True;
1887 /***************************************************************************
1888 Append a jobid to the 'jobs changed' list.
1889 ***************************************************************************/
1891 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1893 TDB_DATA data, key;
1895 key.dptr = "INFO/jobs_changed";
1896 key.dsize = strlen(key.dptr);
1897 data.dptr = (char *)&jobid;
1898 data.dsize = 4;
1900 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1902 return (tdb_append(pdb->tdb, key, data) == 0);
1905 /***************************************************************************
1906 Start spooling a job - return the jobid.
1907 ***************************************************************************/
1909 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1911 uint32 jobid;
1912 char *path;
1913 struct printjob pjob;
1914 user_struct *vuser;
1915 const char *printername = lp_const_servicename(snum);
1916 struct tdb_print_db *pdb = get_print_db_byname(printername);
1917 int njobs;
1919 errno = 0;
1921 if (!pdb)
1922 return (uint32)-1;
1924 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1925 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1926 release_print_db(pdb);
1927 return (uint32)-1;
1930 if (!print_time_access_check(snum)) {
1931 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1932 release_print_db(pdb);
1933 return (uint32)-1;
1936 path = lp_pathname(snum);
1938 /* see if we have sufficient disk space */
1939 if (lp_minprintspace(snum)) {
1940 SMB_BIG_UINT dspace, dsize;
1941 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1942 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1943 DEBUG(3, ("print_job_start: disk space check failed.\n"));
1944 release_print_db(pdb);
1945 errno = ENOSPC;
1946 return (uint32)-1;
1950 /* for autoloaded printers, check that the printcap entry still exists */
1951 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1952 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1953 release_print_db(pdb);
1954 errno = ENOENT;
1955 return (uint32)-1;
1958 /* Insure the maximum queue size is not violated */
1959 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1960 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1961 printername, njobs, lp_maxprintjobs(snum) ));
1962 release_print_db(pdb);
1963 errno = ENOSPC;
1964 return (uint32)-1;
1967 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1968 printername, njobs, lp_maxprintjobs(snum) ));
1970 if (!allocate_print_jobid(pdb, snum, printername, &jobid))
1971 goto fail;
1973 /* create the database entry */
1975 ZERO_STRUCT(pjob);
1977 pjob.pid = local_pid;
1978 pjob.sysjob = -1;
1979 pjob.fd = -1;
1980 pjob.starttime = time(NULL);
1981 pjob.status = LPQ_SPOOLING;
1982 pjob.size = 0;
1983 pjob.spooled = False;
1984 pjob.smbjob = True;
1985 pjob.nt_devmode = nt_devmode;
1987 fstrcpy(pjob.jobname, jobname);
1989 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1990 fstrcpy(pjob.user, vuser->user.smb_name);
1991 } else {
1992 fstrcpy(pjob.user, uidtoname(user->uid));
1995 fstrcpy(pjob.queuename, lp_const_servicename(snum));
1997 /* we have a job entry - now create the spool file */
1998 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
1999 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2000 pjob.fd = smb_mkstemp(pjob.filename);
2002 if (pjob.fd == -1) {
2003 if (errno == EACCES) {
2004 /* Common setup error, force a report. */
2005 DEBUG(0, ("print_job_start: insufficient permissions \
2006 to open spool file %s.\n", pjob.filename));
2007 } else {
2008 /* Normal case, report at level 3 and above. */
2009 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2010 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2012 goto fail;
2015 pjob_store(snum, jobid, &pjob);
2017 /* Update the 'jobs changed' entry used by print_queue_status. */
2018 add_to_jobs_changed(pdb, jobid);
2020 /* Ensure we keep a rough count of the number of total jobs... */
2021 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2023 release_print_db(pdb);
2025 return jobid;
2027 fail:
2028 if (jobid != -1)
2029 pjob_delete(snum, jobid);
2031 release_print_db(pdb);
2033 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2034 return (uint32)-1;
2037 /****************************************************************************
2038 Update the number of pages spooled to jobid
2039 ****************************************************************************/
2041 void print_job_endpage(int snum, uint32 jobid)
2043 struct printjob *pjob = print_job_find(snum, jobid);
2044 if (!pjob)
2045 return;
2046 /* don't allow another process to get this info - it is meaningless */
2047 if (pjob->pid != local_pid)
2048 return;
2050 pjob->page_count++;
2051 pjob_store(snum, jobid, pjob);
2054 /****************************************************************************
2055 Print a file - called on closing the file. This spools the job.
2056 If normal close is false then we're tearing down the jobs - treat as an
2057 error.
2058 ****************************************************************************/
2060 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2062 struct printjob *pjob = print_job_find(snum, jobid);
2063 int ret;
2064 SMB_STRUCT_STAT sbuf;
2065 struct printif *current_printif = get_printer_fns( snum );
2067 if (!pjob)
2068 return False;
2070 if (pjob->spooled || pjob->pid != local_pid)
2071 return False;
2073 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2074 pjob->size = sbuf.st_size;
2075 close(pjob->fd);
2076 pjob->fd = -1;
2077 } else {
2080 * Not a normal close or we couldn't stat the job file,
2081 * so something has gone wrong. Cleanup.
2083 close(pjob->fd);
2084 pjob->fd = -1;
2085 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2086 goto fail;
2089 /* Technically, this is not quite right. If the printer has a separator
2090 * page turned on, the NT spooler prints the separator page even if the
2091 * print job is 0 bytes. 010215 JRR */
2092 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2093 /* don't bother spooling empty files or something being deleted. */
2094 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2095 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2096 unlink(pjob->filename);
2097 pjob_delete(snum, jobid);
2098 return True;
2101 pjob->smbjob = jobid;
2103 ret = (*(current_printif->job_submit))(snum, pjob);
2105 if (ret)
2106 goto fail;
2108 /* The print job has been sucessfully handed over to the back-end */
2110 pjob->spooled = True;
2111 pjob->status = LPQ_QUEUED;
2112 pjob_store(snum, jobid, pjob);
2114 /* make sure the database is up to date */
2115 if (print_cache_expired(snum))
2116 print_queue_update(snum);
2118 return True;
2120 fail:
2122 /* The print job was not succesfully started. Cleanup */
2123 /* Still need to add proper error return propagation! 010122:JRR */
2124 unlink(pjob->filename);
2125 pjob_delete(snum, jobid);
2126 remove_from_jobs_changed(snum, jobid);
2127 return False;
2130 /****************************************************************************
2131 Get a snapshot of jobs in the system without traversing.
2132 ****************************************************************************/
2134 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2136 TDB_DATA data, key, cgdata;
2137 print_queue_struct *queue = NULL;
2138 uint32 qcount = 0;
2139 uint32 extra_count = 0;
2140 int total_count = 0;
2141 size_t len = 0;
2142 uint32 i;
2143 int max_reported_jobs = lp_max_reported_jobs(snum);
2144 BOOL ret = False;
2146 /* make sure the database is up to date */
2147 if (print_cache_expired(snum))
2148 print_queue_update(snum);
2150 *pcount = 0;
2151 *ppqueue = NULL;
2153 ZERO_STRUCT(data);
2154 ZERO_STRUCT(cgdata);
2155 key.dptr = "INFO/linear_queue_array";
2156 key.dsize = strlen(key.dptr);
2158 /* Get the stored queue data. */
2159 data = tdb_fetch(pdb->tdb, key);
2161 if (data.dptr && data.dsize >= sizeof(qcount))
2162 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2164 /* Get the changed jobs list. */
2165 key.dptr = "INFO/jobs_changed";
2166 key.dsize = strlen(key.dptr);
2168 cgdata = tdb_fetch(pdb->tdb, key);
2169 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2170 extra_count = cgdata.dsize/4;
2172 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2174 /* Allocate the queue size. */
2175 if (qcount == 0 && extra_count == 0)
2176 goto out;
2178 if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2179 goto out;
2181 /* Retrieve the linearised queue data. */
2183 for( i = 0; i < qcount; i++) {
2184 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2185 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2186 &qjob,
2187 &qsize,
2188 &qpage_count,
2189 &qstatus,
2190 &qpriority,
2191 &qtime,
2192 queue[i].fs_user,
2193 queue[i].fs_file);
2194 queue[i].job = qjob;
2195 queue[i].size = qsize;
2196 queue[i].page_count = qpage_count;
2197 queue[i].status = qstatus;
2198 queue[i].priority = qpriority;
2199 queue[i].time = qtime;
2202 total_count = qcount;
2204 /* Add in the changed jobids. */
2205 for( i = 0; i < extra_count; i++) {
2206 uint32 jobid;
2207 struct printjob *pjob;
2209 jobid = IVAL(cgdata.dptr, i*4);
2210 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2211 pjob = print_job_find(snum, jobid);
2212 if (!pjob) {
2213 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2214 remove_from_jobs_changed(snum, jobid);
2215 continue;
2218 queue[total_count].job = jobid;
2219 queue[total_count].size = pjob->size;
2220 queue[total_count].page_count = pjob->page_count;
2221 queue[total_count].status = pjob->status;
2222 queue[total_count].priority = 1;
2223 queue[total_count].time = pjob->starttime;
2224 fstrcpy(queue[total_count].fs_user, pjob->user);
2225 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2226 total_count++;
2229 /* Sort the queue by submission time otherwise they are displayed
2230 in hash order. */
2232 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2234 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2236 if (max_reported_jobs && total_count > max_reported_jobs)
2237 total_count = max_reported_jobs;
2239 *ppqueue = queue;
2240 *pcount = total_count;
2242 ret = True;
2244 out:
2246 SAFE_FREE(data.dptr);
2247 SAFE_FREE(cgdata.dptr);
2248 return ret;
2251 /****************************************************************************
2252 Get a printer queue listing.
2253 set queue = NULL and status = NULL if you just want to update the cache
2254 ****************************************************************************/
2256 int print_queue_status(int snum,
2257 print_queue_struct **ppqueue,
2258 print_status_struct *status)
2260 fstring keystr;
2261 TDB_DATA data, key;
2262 const char *printername;
2263 struct tdb_print_db *pdb;
2264 int count = 0;
2266 /* make sure the database is up to date */
2268 if (print_cache_expired(snum))
2269 print_queue_update(snum);
2271 /* return if we are done */
2272 if ( !ppqueue || !status )
2273 return 0;
2275 *ppqueue = NULL;
2276 printername = lp_const_servicename(snum);
2277 pdb = get_print_db_byname(printername);
2279 if (!pdb)
2280 return 0;
2283 * Fetch the queue status. We must do this first, as there may
2284 * be no jobs in the queue.
2287 ZERO_STRUCTP(status);
2288 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2289 key.dptr = keystr;
2290 key.dsize = strlen(keystr);
2291 data = tdb_fetch(pdb->tdb, key);
2292 if (data.dptr) {
2293 if (data.dsize == sizeof(*status)) {
2294 /* this memcpy is ok since the status struct was
2295 not packed before storing it in the tdb */
2296 memcpy(status, data.dptr, sizeof(*status));
2298 SAFE_FREE(data.dptr);
2302 * Now, fetch the print queue information. We first count the number
2303 * of entries, and then only retrieve the queue if necessary.
2306 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2307 release_print_db(pdb);
2308 return 0;
2311 release_print_db(pdb);
2312 return count;
2315 /****************************************************************************
2316 Pause a queue.
2317 ****************************************************************************/
2319 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2321 int ret;
2322 struct printif *current_printif = get_printer_fns( snum );
2324 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2325 *errcode = WERR_ACCESS_DENIED;
2326 return False;
2329 ret = (*(current_printif->queue_pause))(snum);
2331 if (ret != 0) {
2332 *errcode = WERR_INVALID_PARAM;
2333 return False;
2336 /* force update the database */
2337 print_cache_flush(snum);
2339 /* Send a printer notify message */
2341 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2343 return True;
2346 /****************************************************************************
2347 Resume a queue.
2348 ****************************************************************************/
2350 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2352 int ret;
2353 struct printif *current_printif = get_printer_fns( snum );
2355 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2356 *errcode = WERR_ACCESS_DENIED;
2357 return False;
2360 ret = (*(current_printif->queue_resume))(snum);
2362 if (ret != 0) {
2363 *errcode = WERR_INVALID_PARAM;
2364 return False;
2367 /* make sure the database is up to date */
2368 if (print_cache_expired(snum))
2369 print_queue_update(snum);
2371 /* Send a printer notify message */
2373 notify_printer_status(snum, PRINTER_STATUS_OK);
2375 return True;
2378 /****************************************************************************
2379 Purge a queue - implemented by deleting all jobs that we can delete.
2380 ****************************************************************************/
2382 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2384 print_queue_struct *queue;
2385 print_status_struct status;
2386 int njobs, i;
2387 BOOL can_job_admin;
2389 /* Force and update so the count is accurate (i.e. not a cached count) */
2390 print_queue_update(snum);
2392 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2393 njobs = print_queue_status(snum, &queue, &status);
2395 for (i=0;i<njobs;i++) {
2396 BOOL owner = is_owner(user, snum, queue[i].job);
2398 if (owner || can_job_admin) {
2399 print_job_delete1(snum, queue[i].job);
2403 SAFE_FREE(queue);
2405 return True;