bug 770; correct fix this time; Make sure that we send the SMBjobid for unix jobs...
[Samba/bb.git] / source3 / printing / printing.c
blob1f0bb1e0742673103986b9b1fa365239da66b87a
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 struct printif *current_printif = &generic_printif;
28 static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
30 /*
31 the printing backend revolves around a tdb database that stores the
32 SMB view of the print queue
34 The key for this database is a jobid - a internally generated number that
35 uniquely identifies a print job
37 reading the print queue involves two steps:
38 - possibly running lpq and updating the internal database from that
39 - reading entries from the database
41 jobids are assigned when a job starts spooling.
44 /***************************************************************************
45 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
46 bit RPC jobids.... JRA.
47 ***************************************************************************/
49 static TDB_CONTEXT *rap_tdb;
50 static uint16 next_rap_jobid;
52 uint16 pjobid_to_rap(int snum, uint32 jobid)
54 uint16 rap_jobid;
55 TDB_DATA data, key;
56 char jinfo[8];
58 DEBUG(10,("pjobid_to_rap: called.\n"));
60 if (!rap_tdb) {
61 /* Create the in-memory tdb. */
62 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
63 if (!rap_tdb)
64 return 0;
67 SIVAL(&jinfo,0,(int32)snum);
68 SIVAL(&jinfo,4,jobid);
70 key.dptr = (char *)&jinfo;
71 key.dsize = sizeof(jinfo);
72 data = tdb_fetch(rap_tdb, key);
73 if (data.dptr && data.dsize == sizeof(uint16)) {
74 rap_jobid = SVAL(data.dptr, 0);
75 SAFE_FREE(data.dptr);
76 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
77 (unsigned int)jobid,
78 (unsigned int)rap_jobid));
79 return rap_jobid;
81 SAFE_FREE(data.dptr);
82 /* Not found - create and store mapping. */
83 rap_jobid = ++next_rap_jobid;
84 if (rap_jobid == 0)
85 rap_jobid = ++next_rap_jobid;
86 data.dptr = (char *)&rap_jobid;
87 data.dsize = sizeof(rap_jobid);
88 tdb_store(rap_tdb, key, data, TDB_REPLACE);
89 tdb_store(rap_tdb, data, key, TDB_REPLACE);
91 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
92 (unsigned int)jobid,
93 (unsigned int)rap_jobid));
94 return rap_jobid;
97 BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
99 TDB_DATA data, key;
101 DEBUG(10,("rap_to_pjobid called.\n"));
103 if (!rap_tdb)
104 return False;
106 key.dptr = (char *)&rap_jobid;
107 key.dsize = sizeof(rap_jobid);
108 data = tdb_fetch(rap_tdb, key);
109 if (data.dptr && data.dsize == 8) {
110 *psnum = IVAL(data.dptr,0);
111 *pjobid = IVAL(data.dptr,4);
112 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
113 (unsigned int)*pjobid,
114 (unsigned int)rap_jobid));
115 SAFE_FREE(data.dptr);
116 return True;
119 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
120 (unsigned int)rap_jobid));
121 SAFE_FREE(data.dptr);
122 return False;
125 static void rap_jobid_delete(int snum, uint32 jobid)
127 TDB_DATA key, data;
128 uint16 rap_jobid;
129 char jinfo[8];
131 DEBUG(10,("rap_jobid_delete: called.\n"));
133 if (!rap_tdb)
134 return;
136 SIVAL(&jinfo,0,(int32)snum);
137 SIVAL(&jinfo,4,jobid);
139 key.dptr = (char *)&jinfo;
140 key.dsize = sizeof(jinfo);
141 data = tdb_fetch(rap_tdb, key);
142 if (!data.dptr || (data.dsize != sizeof(uint16))) {
143 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
144 (unsigned int)jobid ));
145 SAFE_FREE(data.dptr);
146 return;
149 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
150 (unsigned int)jobid ));
152 rap_jobid = SVAL(data.dptr, 0);
153 SAFE_FREE(data.dptr);
154 data.dptr = (char *)&rap_jobid;
155 data.dsize = sizeof(rap_jobid);
156 tdb_delete(rap_tdb, key);
157 tdb_delete(rap_tdb, data);
160 static pid_t local_pid;
162 static int get_queue_status(int, print_status_struct *);
164 /****************************************************************************
165 Initialise the printing backend. Called once at startup before the fork().
166 ****************************************************************************/
168 BOOL print_backend_init(void)
170 const char *sversion = "INFO/version";
171 pstring printing_path;
172 int services = lp_numservices();
173 int snum;
175 if (local_pid == sys_getpid())
176 return True;
178 unlink(lock_path("printing.tdb"));
179 pstrcpy(printing_path,lock_path("printing"));
180 mkdir(printing_path,0755);
182 local_pid = sys_getpid();
184 /* handle a Samba upgrade */
186 for (snum = 0; snum < services; snum++) {
187 struct tdb_print_db *pdb;
188 if (!lp_print_ok(snum))
189 continue;
191 pdb = get_print_db_byname(lp_const_servicename(snum));
192 if (!pdb)
193 continue;
194 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
195 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
196 release_print_db(pdb);
197 return False;
199 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
200 tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
201 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
203 tdb_unlock_bystring(pdb->tdb, sversion);
204 release_print_db(pdb);
207 close_all_print_db(); /* Don't leave any open. */
209 /* select the appropriate printing interface... */
210 #ifdef HAVE_CUPS
211 if (strcmp(lp_printcapname(), "cups") == 0)
212 current_printif = &cups_printif;
213 #endif /* HAVE_CUPS */
215 /* do NT print initialization... */
216 return nt_printing_init();
219 /****************************************************************************
220 Shut down printing backend. Called once at shutdown to close the tdb.
221 ****************************************************************************/
223 void printing_end(void)
225 close_all_print_db(); /* Don't leave any open. */
228 /****************************************************************************
229 Useful function to generate a tdb key.
230 ****************************************************************************/
232 static TDB_DATA print_key(uint32 jobid)
234 static uint32 j;
235 TDB_DATA ret;
237 j = jobid;
238 ret.dptr = (void *)&j;
239 ret.dsize = sizeof(j);
240 return ret;
243 /***********************************************************************
244 unpack a pjob from a tdb buffer
245 ***********************************************************************/
247 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
249 int len = 0;
250 int used;
251 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
252 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
254 if ( !buf || !pjob )
255 return -1;
257 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
258 &pjpid,
259 &pjsysjob,
260 &pjfd,
261 &pjstarttime,
262 &pjstatus,
263 &pjsize,
264 &pjpage_count,
265 &pjspooled,
266 &pjsmbjob,
267 pjob->filename,
268 pjob->jobname,
269 pjob->user,
270 pjob->queuename);
272 if ( len == -1 )
273 return -1;
275 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
276 return -1;
278 len += used;
280 pjob->pid = pjpid;
281 pjob->sysjob = pjsysjob;
282 pjob->fd = pjfd;
283 pjob->starttime = pjstarttime;
284 pjob->status = pjstatus;
285 pjob->size = pjsize;
286 pjob->page_count = pjpage_count;
287 pjob->spooled = pjspooled;
288 pjob->smbjob = pjsmbjob;
290 return len;
294 /****************************************************************************
295 Useful function to find a print job in the database.
296 ****************************************************************************/
298 static struct printjob *print_job_find(int snum, uint32 jobid)
300 static struct printjob pjob;
301 TDB_DATA ret;
302 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
305 if (!pdb)
306 return NULL;
308 ret = tdb_fetch(pdb->tdb, print_key(jobid));
309 release_print_db(pdb);
311 if (!ret.dptr)
312 return NULL;
314 if ( pjob.nt_devmode )
315 free_nt_devicemode( &pjob.nt_devmode );
317 ZERO_STRUCT( pjob );
319 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
320 SAFE_FREE(ret.dptr);
321 return NULL;
324 SAFE_FREE(ret.dptr);
325 return &pjob;
328 /* Convert a unix jobid to a smb jobid */
330 static uint32 sysjob_to_jobid_value;
332 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
333 TDB_DATA data, void *state)
335 struct printjob *pjob;
336 int *sysjob = (int *)state;
338 if (!data.dptr || data.dsize == 0)
339 return 0;
341 pjob = (struct printjob *)data.dptr;
342 if (key.dsize != sizeof(uint32))
343 return 0;
345 if (*sysjob == pjob->sysjob) {
346 uint32 *jobid = (uint32 *)key.dptr;
348 sysjob_to_jobid_value = *jobid;
349 return 1;
352 return 0;
355 /****************************************************************************
356 This is a *horribly expensive call as we have to iterate through all the
357 current printer tdb's. Don't do this often ! JRA.
358 ****************************************************************************/
360 uint32 sysjob_to_jobid(int unix_jobid)
362 int services = lp_numservices();
363 int snum;
365 sysjob_to_jobid_value = (uint32)-1;
367 for (snum = 0; snum < services; snum++) {
368 struct tdb_print_db *pdb;
369 if (!lp_print_ok(snum))
370 continue;
371 pdb = get_print_db_byname(lp_const_servicename(snum));
372 if (pdb)
373 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
374 release_print_db(pdb);
375 if (sysjob_to_jobid_value != (uint32)-1)
376 return sysjob_to_jobid_value;
378 return (uint32)-1;
381 /****************************************************************************
382 Send notifications based on what has changed after a pjob_store.
383 ****************************************************************************/
385 static struct {
386 uint32 lpq_status;
387 uint32 spoolss_status;
388 } lpq_to_spoolss_status_map[] = {
389 { LPQ_QUEUED, JOB_STATUS_QUEUED },
390 { LPQ_PAUSED, JOB_STATUS_PAUSED },
391 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
392 { LPQ_PRINTING, JOB_STATUS_PRINTING },
393 { LPQ_DELETING, JOB_STATUS_DELETING },
394 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
395 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
396 { LPQ_PRINTED, JOB_STATUS_PRINTED },
397 { LPQ_DELETED, JOB_STATUS_DELETED },
398 { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
399 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
400 { -1, 0 }
403 /* Convert a lpq status value stored in printing.tdb into the
404 appropriate win32 API constant. */
406 static uint32 map_to_spoolss_status(uint32 lpq_status)
408 int i = 0;
410 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
411 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
412 return lpq_to_spoolss_status_map[i].spoolss_status;
413 i++;
416 return 0;
419 static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
420 struct printjob *new_data)
422 BOOL new_job = False;
424 if (!old_data)
425 new_job = True;
427 /* Notify the job name first */
429 if (new_job || !strequal(old_data->jobname, new_data->jobname))
430 notify_job_name(snum, jobid, new_data->jobname);
432 /* Job attributes that can't be changed. We only send
433 notification for these on a new job. */
435 if (new_job) {
436 notify_job_submitted(snum, jobid, new_data->starttime);
437 notify_job_username(snum, jobid, new_data->user);
440 /* Job attributes of a new job or attributes that can be
441 modified. */
443 if (new_job || old_data->status != new_data->status)
444 notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
446 if (new_job || old_data->size != new_data->size)
447 notify_job_total_bytes(snum, jobid, new_data->size);
449 if (new_job || old_data->page_count != new_data->page_count)
450 notify_job_total_pages(snum, jobid, new_data->page_count);
453 /****************************************************************************
454 Store a job structure back to the database.
455 ****************************************************************************/
457 static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
459 TDB_DATA old_data, new_data;
460 BOOL ret = False;
461 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
462 char *buf = NULL;
463 int len, newlen, buflen;
466 if (!pdb)
467 return False;
469 /* Get old data */
471 old_data = tdb_fetch(pdb->tdb, print_key(jobid));
473 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
475 newlen = 0;
477 do {
478 len = 0;
479 buflen = newlen;
480 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
481 (uint32)pjob->pid,
482 (uint32)pjob->sysjob,
483 (uint32)pjob->fd,
484 (uint32)pjob->starttime,
485 (uint32)pjob->status,
486 (uint32)pjob->size,
487 (uint32)pjob->page_count,
488 (uint32)pjob->spooled,
489 (uint32)pjob->smbjob,
490 pjob->filename,
491 pjob->jobname,
492 pjob->user,
493 pjob->queuename);
495 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
497 if (buflen != len) {
498 char *tb;
500 tb = (char *)Realloc(buf, len);
501 if (!tb) {
502 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
503 goto done;
505 else
506 buf = tb;
507 newlen = len;
509 } while ( buflen != len );
512 /* Store new data */
514 new_data.dptr = buf;
515 new_data.dsize = len;
516 ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
518 release_print_db(pdb);
520 /* Send notify updates for what has changed */
522 if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) )
523 pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob );
525 done:
526 SAFE_FREE( old_data.dptr );
527 SAFE_FREE( buf );
529 return ret;
532 /****************************************************************************
533 Remove a job structure from the database.
534 ****************************************************************************/
536 void pjob_delete(int snum, uint32 jobid)
538 struct printjob *pjob = print_job_find(snum, jobid);
539 uint32 job_status = 0;
540 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
542 if (!pdb)
543 return;
545 if (!pjob) {
546 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
547 (unsigned int)jobid));
548 release_print_db(pdb);
549 return;
552 /* Send a notification that a job has been deleted */
554 job_status = map_to_spoolss_status(pjob->status);
556 /* We must cycle through JOB_STATUS_DELETING and
557 JOB_STATUS_DELETED for the port monitor to delete the job
558 properly. */
560 job_status |= JOB_STATUS_DELETING;
561 notify_job_status(snum, jobid, job_status);
563 job_status |= JOB_STATUS_DELETED;
564 notify_job_status(snum, jobid, job_status);
566 /* Remove from printing.tdb */
568 tdb_delete(pdb->tdb, print_key(jobid));
569 release_print_db(pdb);
570 rap_jobid_delete(snum, jobid);
573 /****************************************************************************
574 Parse a file name from the system spooler to generate a jobid.
575 ****************************************************************************/
577 static uint32 print_parse_jobid(char *fname)
579 int jobid;
581 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
582 return (uint32)-1;
583 fname += strlen(PRINT_SPOOL_PREFIX);
585 jobid = atoi(fname);
586 if (jobid <= 0)
587 return (uint32)-1;
589 return (uint32)jobid;
592 /****************************************************************************
593 List a unix job in the print database.
594 ****************************************************************************/
596 static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
598 struct printjob pj, *old_pj;
600 if (jobid == (uint32)-1)
601 jobid = q->job + UNIX_JOB_START;
603 /* Preserve the timestamp on an existing unix print job */
605 old_pj = print_job_find(snum, jobid);
607 ZERO_STRUCT(pj);
609 pj.pid = (pid_t)-1;
610 pj.sysjob = q->job;
611 pj.fd = -1;
612 pj.starttime = old_pj ? old_pj->starttime : q->time;
613 pj.status = q->status;
614 pj.size = q->size;
615 pj.spooled = True;
616 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
617 if (jobid < UNIX_JOB_START) {
618 pj.smbjob = True;
619 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
620 } else {
621 pj.smbjob = False;
622 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
624 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
625 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
627 pjob_store(snum, jobid, &pj);
631 struct traverse_struct {
632 print_queue_struct *queue;
633 int qcount, snum, maxcount, total_jobs;
634 time_t lpq_time;
637 /****************************************************************************
638 Utility fn to delete any jobs that are no longer active.
639 ****************************************************************************/
641 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
643 struct traverse_struct *ts = (struct traverse_struct *)state;
644 struct printjob pjob;
645 uint32 jobid;
646 int i;
648 if ( key.dsize != sizeof(jobid) )
649 return 0;
651 jobid = IVAL(key.dptr, 0);
652 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
653 return 0;
654 free_nt_devicemode( &pjob.nt_devmode );
657 if (ts->snum != lp_servicenumber(pjob.queuename)) {
658 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
659 return 0;
662 if (!pjob.smbjob) {
663 /* remove a unix job if it isn't in the system queue any more */
665 for (i=0;i<ts->qcount;i++) {
666 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
667 if (jobid == u_jobid)
668 break;
670 if (i == ts->qcount) {
671 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
672 (unsigned int)jobid ));
673 pjob_delete(ts->snum, jobid);
674 return 0;
677 /* need to continue the the bottom of the function to
678 save the correct attributes */
681 /* maybe it hasn't been spooled yet */
682 if (!pjob.spooled) {
683 /* if a job is not spooled and the process doesn't
684 exist then kill it. This cleans up after smbd
685 deaths */
686 if (!process_exists(pjob.pid)) {
687 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
688 (unsigned int)jobid, (unsigned int)pjob.pid ));
689 pjob_delete(ts->snum, jobid);
690 } else
691 ts->total_jobs++;
692 return 0;
695 /* this check only makes sense for jobs submitted from Windows clients */
697 if ( pjob.smbjob ) {
698 for (i=0;i<ts->qcount;i++) {
699 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
700 if (jobid == curr_jobid)
701 break;
705 /* The job isn't in the system queue - we have to assume it has
706 completed, so delete the database entry. */
708 if (i == ts->qcount) {
710 /* A race can occur between the time a job is spooled and
711 when it appears in the lpq output. This happens when
712 the job is added to printing.tdb when another smbd
713 running print_queue_update() has completed a lpq and
714 is currently traversing the printing tdb and deleting jobs.
715 Don't delete the job if it was submitted after the lpq_time. */
717 if (pjob.starttime < ts->lpq_time) {
718 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
719 (unsigned int)jobid,
720 (unsigned int)pjob.starttime,
721 (unsigned int)ts->lpq_time ));
722 pjob_delete(ts->snum, jobid);
723 } else
724 ts->total_jobs++;
725 return 0;
728 /* Save the pjob attributes we will store. */
729 /* FIXME!!! This is the only place where queue->job
730 represents the SMB jobid --jerry */
731 ts->queue[i].job = jobid;
732 ts->queue[i].size = pjob.size;
733 ts->queue[i].page_count = pjob.page_count;
734 ts->queue[i].status = pjob.status;
735 ts->queue[i].priority = 1;
736 ts->queue[i].time = pjob.starttime;
737 fstrcpy(ts->queue[i].fs_user, pjob.user);
738 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
740 ts->total_jobs++;
742 return 0;
745 /****************************************************************************
746 Check if the print queue has been updated recently enough.
747 ****************************************************************************/
749 static void print_cache_flush(int snum)
751 fstring key;
752 const char *printername = lp_const_servicename(snum);
753 struct tdb_print_db *pdb = get_print_db_byname(printername);
755 if (!pdb)
756 return;
757 slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
758 tdb_store_int32(pdb->tdb, key, -1);
759 release_print_db(pdb);
762 /****************************************************************************
763 Check if someone already thinks they are doing the update.
764 ****************************************************************************/
766 static pid_t get_updating_pid(fstring printer_name)
768 fstring keystr;
769 TDB_DATA data, key;
770 pid_t updating_pid;
771 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
773 if (!pdb)
774 return (pid_t)-1;
775 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
776 key.dptr = keystr;
777 key.dsize = strlen(keystr);
779 data = tdb_fetch(pdb->tdb, key);
780 release_print_db(pdb);
781 if (!data.dptr || data.dsize != sizeof(pid_t)) {
782 SAFE_FREE(data.dptr);
783 return (pid_t)-1;
786 updating_pid = IVAL(data.dptr, 0);
787 SAFE_FREE(data.dptr);
789 if (process_exists(updating_pid))
790 return updating_pid;
792 return (pid_t)-1;
795 /****************************************************************************
796 Set the fact that we're doing the update, or have finished doing the update
797 in the tdb.
798 ****************************************************************************/
800 static void set_updating_pid(const fstring printer_name, BOOL delete)
802 fstring keystr;
803 TDB_DATA key;
804 TDB_DATA data;
805 pid_t updating_pid = sys_getpid();
806 struct tdb_print_db *pdb = get_print_db_byname(printer_name);
808 if (!pdb)
809 return;
811 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
812 key.dptr = keystr;
813 key.dsize = strlen(keystr);
815 if (delete) {
816 tdb_delete(pdb->tdb, key);
817 release_print_db(pdb);
818 return;
821 data.dptr = (void *)&updating_pid;
822 data.dsize = sizeof(pid_t);
824 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
825 release_print_db(pdb);
828 /****************************************************************************
829 Sort print jobs by submittal time.
830 ****************************************************************************/
832 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
834 /* Silly cases */
836 if (!j1 && !j2)
837 return 0;
838 if (!j1)
839 return -1;
840 if (!j2)
841 return 1;
843 /* Sort on job start time */
845 if (j1->time == j2->time)
846 return 0;
847 return (j1->time > j2->time) ? 1 : -1;
850 /****************************************************************************
851 Store the sorted queue representation for later portmon retrieval.
852 ****************************************************************************/
854 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
856 TDB_DATA data, key;
857 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
858 print_queue_struct *queue = pts->queue;
859 size_t len;
860 size_t i;
861 uint qcount;
863 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
864 pts->qcount = max_reported_jobs;
865 qcount = pts->qcount;
867 /* Work out the size. */
868 data.dsize = 0;
869 data.dsize += tdb_pack(NULL, 0, "d", qcount);
871 for (i = 0; i < pts->qcount; i++) {
872 data.dsize += tdb_pack(NULL, 0, "ddddddff",
873 (uint32)queue[i].job,
874 (uint32)queue[i].size,
875 (uint32)queue[i].page_count,
876 (uint32)queue[i].status,
877 (uint32)queue[i].priority,
878 (uint32)queue[i].time,
879 queue[i].fs_user,
880 queue[i].fs_file);
883 if ((data.dptr = malloc(data.dsize)) == NULL)
884 return;
886 len = 0;
887 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
888 for (i = 0; i < pts->qcount; i++) {
889 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
890 (uint32)queue[i].job,
891 (uint32)queue[i].size,
892 (uint32)queue[i].page_count,
893 (uint32)queue[i].status,
894 (uint32)queue[i].priority,
895 (uint32)queue[i].time,
896 queue[i].fs_user,
897 queue[i].fs_file);
900 key.dptr = "INFO/linear_queue_array";
901 key.dsize = strlen(key.dptr);
902 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
903 SAFE_FREE(data.dptr);
904 return;
907 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
909 TDB_DATA data, key;
911 key.dptr = "INFO/jobs_changed";
912 key.dsize = strlen(key.dptr);
913 ZERO_STRUCT(data);
915 data = tdb_fetch(pdb->tdb, key);
916 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
917 SAFE_FREE(data.dptr);
918 ZERO_STRUCT(data);
921 return data;
924 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
926 unsigned int i;
927 unsigned int job_count = data.dsize / 4;
929 for (i = 0; i < job_count; i++) {
930 uint32 ch_jobid;
932 ch_jobid = IVAL(data.dptr, i*4);
933 if (ch_jobid == jobid)
934 remove_from_jobs_changed(snum, jobid);
938 /****************************************************************************
939 Update the internal database from the system print queue for a queue.
940 ****************************************************************************/
942 static void print_queue_update(int snum)
944 int i, qcount;
945 print_queue_struct *queue = NULL;
946 print_status_struct status;
947 print_status_struct old_status;
948 struct printjob *pjob;
949 struct traverse_struct tstruct;
950 fstring keystr, printer_name, cachestr;
951 TDB_DATA data, key;
952 TDB_DATA jcdata;
953 struct tdb_print_db *pdb;
955 fstrcpy(printer_name, lp_const_servicename(snum));
956 pdb = get_print_db_byname(printer_name);
957 if (!pdb)
958 return;
961 * Check to see if someone else is doing this update.
962 * This is essentially a mutex on the update.
965 if (get_updating_pid(printer_name) != -1) {
966 release_print_db(pdb);
967 return;
970 /* Lock the queue for the database update */
972 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
973 /* Only wait 10 seconds for this. */
974 if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
975 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
976 release_print_db(pdb);
977 return;
981 * Ensure that no one else got in here.
982 * If the updating pid is still -1 then we are
983 * the winner.
986 if (get_updating_pid(printer_name) != -1) {
988 * Someone else is doing the update, exit.
990 tdb_unlock_bystring(pdb->tdb, keystr);
991 release_print_db(pdb);
992 return;
996 * We're going to do the update ourselves.
999 /* Tell others we're doing the update. */
1000 set_updating_pid(printer_name, False);
1003 * Allow others to enter and notice we're doing
1004 * the update.
1007 tdb_unlock_bystring(pdb->tdb, keystr);
1010 * Update the cache time FIRST ! Stops others even
1011 * attempting to get the lock and doing this
1012 * if the lpq takes a long time.
1015 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
1016 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1018 /* get the current queue using the appropriate interface */
1019 ZERO_STRUCT(status);
1021 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
1023 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1024 "s" : "", printer_name));
1026 /* Sort the queue by submission time otherwise they are displayed
1027 in hash order. */
1029 qsort(queue, qcount, sizeof(print_queue_struct),
1030 QSORT_CAST(printjob_comp));
1033 any job in the internal database that is marked as spooled
1034 and doesn't exist in the system queue is considered finished
1035 and removed from the database
1037 any job in the system database but not in the internal database
1038 is added as a unix job
1040 fill in any system job numbers as we go
1043 jcdata = get_jobs_changed_data(pdb);
1045 for (i=0; i<qcount; i++) {
1046 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1048 if (jobid == (uint32)-1) {
1049 /* assume its a unix print job */
1050 print_unix_job(snum, &queue[i], jobid);
1051 continue;
1054 /* we have an active SMB print job - update its status */
1055 pjob = print_job_find(snum, jobid);
1056 if (!pjob) {
1057 /* err, somethings wrong. Probably smbd was restarted
1058 with jobs in the queue. All we can do is treat them
1059 like unix jobs. Pity. */
1060 print_unix_job(snum, &queue[i], jobid);
1061 continue;
1064 pjob->sysjob = queue[i].job;
1065 pjob->status = queue[i].status;
1066 pjob_store(snum, jobid, pjob);
1067 check_job_changed(snum, jcdata, jobid);
1070 SAFE_FREE(jcdata.dptr);
1072 /* now delete any queued entries that don't appear in the
1073 system queue */
1074 tstruct.queue = queue;
1075 tstruct.qcount = qcount;
1076 tstruct.snum = snum;
1077 tstruct.total_jobs = 0;
1078 tstruct.lpq_time = time(NULL);
1080 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1082 /* Store the linearised queue, max jobs only. */
1083 store_queue_struct(pdb, &tstruct);
1085 SAFE_FREE(tstruct.queue);
1087 DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1088 printer_name, tstruct.total_jobs ));
1090 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1092 get_queue_status(snum, &old_status);
1093 if (old_status.qcount != qcount)
1094 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1095 old_status.qcount, qcount, printer_name ));
1097 /* store the new queue status structure */
1098 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1099 key.dptr = keystr;
1100 key.dsize = strlen(keystr);
1102 status.qcount = qcount;
1103 data.dptr = (void *)&status;
1104 data.dsize = sizeof(status);
1105 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1108 * Update the cache time again. We want to do this call
1109 * as little as possible...
1112 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1113 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1115 /* Delete our pid from the db. */
1116 set_updating_pid(printer_name, True);
1117 release_print_db(pdb);
1120 /****************************************************************************
1121 Create/Update an entry in the print tdb that will allow us to send notify
1122 updates only to interested smbd's.
1123 ****************************************************************************/
1125 BOOL print_notify_register_pid(int snum)
1127 TDB_DATA data;
1128 struct tdb_print_db *pdb = NULL;
1129 TDB_CONTEXT *tdb = NULL;
1130 const char *printername;
1131 uint32 mypid = (uint32)sys_getpid();
1132 BOOL ret = False;
1133 size_t i;
1135 /* if (snum == -1), then the change notify request was
1136 on a print server handle and we need to register on
1137 all print queus */
1139 if (snum == -1)
1141 int num_services = lp_numservices();
1142 int idx;
1144 for ( idx=0; idx<num_services; idx++ ) {
1145 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1146 print_notify_register_pid(idx);
1149 return True;
1151 else /* register for a specific printer */
1153 printername = lp_const_servicename(snum);
1154 pdb = get_print_db_byname(printername);
1155 if (!pdb)
1156 return False;
1157 tdb = pdb->tdb;
1160 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1161 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1162 printername));
1163 if (pdb)
1164 release_print_db(pdb);
1165 return False;
1168 data = get_printer_notify_pid_list( tdb, printername, True );
1170 /* Add ourselves and increase the refcount. */
1172 for (i = 0; i < data.dsize; i += 8) {
1173 if (IVAL(data.dptr,i) == mypid) {
1174 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1175 SIVAL(data.dptr, i+4, new_refcount);
1176 break;
1180 if (i == data.dsize) {
1181 /* We weren't in the list. Realloc. */
1182 data.dptr = Realloc(data.dptr, data.dsize + 8);
1183 if (!data.dptr) {
1184 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1185 printername));
1186 goto done;
1188 data.dsize += 8;
1189 SIVAL(data.dptr,data.dsize - 8,mypid);
1190 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1193 /* Store back the record. */
1194 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1195 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1196 list for printer %s\n", printername));
1197 goto done;
1200 ret = True;
1202 done:
1204 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1205 if (pdb)
1206 release_print_db(pdb);
1207 SAFE_FREE(data.dptr);
1208 return ret;
1211 /****************************************************************************
1212 Update an entry in the print tdb that will allow us to send notify
1213 updates only to interested smbd's.
1214 ****************************************************************************/
1216 BOOL print_notify_deregister_pid(int snum)
1218 TDB_DATA data;
1219 struct tdb_print_db *pdb = NULL;
1220 TDB_CONTEXT *tdb = NULL;
1221 const char *printername;
1222 uint32 mypid = (uint32)sys_getpid();
1223 size_t i;
1224 BOOL ret = False;
1226 /* if ( snum == -1 ), we are deregister a print server handle
1227 which means to deregister on all print queues */
1229 if (snum == -1)
1231 int num_services = lp_numservices();
1232 int idx;
1234 for ( idx=0; idx<num_services; idx++ ) {
1235 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1236 print_notify_deregister_pid(idx);
1239 return True;
1241 else /* deregister a specific printer */
1243 printername = lp_const_servicename(snum);
1244 pdb = get_print_db_byname(printername);
1245 if (!pdb)
1246 return False;
1247 tdb = pdb->tdb;
1250 if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1251 DEBUG(0,("print_notify_register_pid: Failed to lock \
1252 printer %s database\n", printername));
1253 if (pdb)
1254 release_print_db(pdb);
1255 return False;
1258 data = get_printer_notify_pid_list( tdb, printername, True );
1260 /* Reduce refcount. Remove ourselves if zero. */
1262 for (i = 0; i < data.dsize; ) {
1263 if (IVAL(data.dptr,i) == mypid) {
1264 uint32 refcount = IVAL(data.dptr, i+4);
1266 refcount--;
1268 if (refcount == 0) {
1269 if (data.dsize - i > 8)
1270 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1271 data.dsize -= 8;
1272 continue;
1274 SIVAL(data.dptr, i+4, refcount);
1277 i += 8;
1280 if (data.dsize == 0)
1281 SAFE_FREE(data.dptr);
1283 /* Store back the record. */
1284 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1285 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1286 list for printer %s\n", printername));
1287 goto done;
1290 ret = True;
1292 done:
1294 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1295 if (pdb)
1296 release_print_db(pdb);
1297 SAFE_FREE(data.dptr);
1298 return ret;
1301 /****************************************************************************
1302 Check if a jobid is valid. It is valid if it exists in the database.
1303 ****************************************************************************/
1305 BOOL print_job_exists(int snum, uint32 jobid)
1307 struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1308 BOOL ret;
1310 if (!pdb)
1311 return False;
1312 ret = tdb_exists(pdb->tdb, print_key(jobid));
1313 release_print_db(pdb);
1314 return ret;
1317 /****************************************************************************
1318 Give the fd used for a jobid.
1319 ****************************************************************************/
1321 int print_job_fd(int snum, uint32 jobid)
1323 struct printjob *pjob = print_job_find(snum, jobid);
1324 if (!pjob)
1325 return -1;
1326 /* don't allow another process to get this info - it is meaningless */
1327 if (pjob->pid != local_pid)
1328 return -1;
1329 return pjob->fd;
1332 /****************************************************************************
1333 Give the filename used for a jobid.
1334 Only valid for the process doing the spooling and when the job
1335 has not been spooled.
1336 ****************************************************************************/
1338 char *print_job_fname(int snum, uint32 jobid)
1340 struct printjob *pjob = print_job_find(snum, jobid);
1341 if (!pjob || pjob->spooled || pjob->pid != local_pid)
1342 return NULL;
1343 return pjob->filename;
1347 /****************************************************************************
1348 Give the filename used for a jobid.
1349 Only valid for the process doing the spooling and when the job
1350 has not been spooled.
1351 ****************************************************************************/
1353 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1355 struct printjob *pjob = print_job_find(snum, jobid);
1357 if ( !pjob )
1358 return NULL;
1360 return pjob->nt_devmode;
1363 /****************************************************************************
1364 Set the place in the queue for a job.
1365 ****************************************************************************/
1367 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1369 DEBUG(2,("print_job_set_place not implemented yet\n"));
1370 return False;
1373 /****************************************************************************
1374 Set the name of a job. Only possible for owner.
1375 ****************************************************************************/
1377 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1379 struct printjob *pjob = print_job_find(snum, jobid);
1380 if (!pjob || pjob->pid != local_pid)
1381 return False;
1383 fstrcpy(pjob->jobname, name);
1384 return pjob_store(snum, jobid, pjob);
1387 /***************************************************************************
1388 Remove a jobid from the 'jobs changed' list.
1389 ***************************************************************************/
1391 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1393 const char *printername = lp_const_servicename(snum);
1394 struct tdb_print_db *pdb = get_print_db_byname(printername);
1395 TDB_DATA data, key;
1396 size_t job_count, i;
1397 BOOL ret = False;
1398 BOOL gotlock = False;
1400 key.dptr = "INFO/jobs_changed";
1401 key.dsize = strlen(key.dptr);
1402 ZERO_STRUCT(data);
1404 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1405 goto out;
1407 gotlock = True;
1409 data = tdb_fetch(pdb->tdb, key);
1411 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1412 goto out;
1414 job_count = data.dsize / 4;
1415 for (i = 0; i < job_count; i++) {
1416 uint32 ch_jobid;
1418 ch_jobid = IVAL(data.dptr, i*4);
1419 if (ch_jobid == jobid) {
1420 if (i < job_count -1 )
1421 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1422 data.dsize -= 4;
1423 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1424 goto out;
1425 break;
1429 ret = True;
1430 out:
1432 if (gotlock)
1433 tdb_chainunlock(pdb->tdb, key);
1434 SAFE_FREE(data.dptr);
1435 release_print_db(pdb);
1436 if (ret)
1437 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1438 else
1439 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1440 return ret;
1443 /****************************************************************************
1444 Delete a print job - don't update queue.
1445 ****************************************************************************/
1447 static BOOL print_job_delete1(int snum, uint32 jobid)
1449 struct printjob *pjob = print_job_find(snum, jobid);
1450 int result = 0;
1452 if (!pjob)
1453 return False;
1456 * If already deleting just return.
1459 if (pjob->status == LPQ_DELETING)
1460 return True;
1462 /* Hrm - we need to be able to cope with deleting a job before it
1463 has reached the spooler. */
1465 if (pjob->sysjob == -1) {
1466 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1469 /* Set the tdb entry to be deleting. */
1471 pjob->status = LPQ_DELETING;
1472 pjob_store(snum, jobid, pjob);
1474 if (pjob->spooled && pjob->sysjob != -1)
1475 result = (*(current_printif->job_delete))(snum, pjob);
1476 else
1477 remove_from_jobs_changed(snum, jobid);
1479 /* Delete the tdb entry if the delete succeeded or the job hasn't
1480 been spooled. */
1482 if (result == 0) {
1483 const char *printername = lp_const_servicename(snum);
1484 struct tdb_print_db *pdb = get_print_db_byname(printername);
1485 int njobs = 1;
1487 if (!pdb)
1488 return False;
1489 pjob_delete(snum, jobid);
1490 /* Ensure we keep a rough count of the number of total jobs... */
1491 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1492 release_print_db(pdb);
1495 return (result == 0);
1498 /****************************************************************************
1499 Return true if the current user owns the print job.
1500 ****************************************************************************/
1502 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1504 struct printjob *pjob = print_job_find(snum, jobid);
1505 user_struct *vuser;
1507 if (!pjob || !user)
1508 return False;
1510 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1511 return strequal(pjob->user, vuser->user.smb_name);
1512 } else {
1513 return strequal(pjob->user, uidtoname(user->uid));
1517 /****************************************************************************
1518 Delete a print job.
1519 ****************************************************************************/
1521 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1523 BOOL owner, deleted;
1524 char *fname;
1526 *errcode = WERR_OK;
1528 owner = is_owner(user, snum, jobid);
1530 /* Check access against security descriptor or whether the user
1531 owns their job. */
1533 if (!owner &&
1534 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1535 DEBUG(3, ("delete denied by security descriptor\n"));
1536 *errcode = WERR_ACCESS_DENIED;
1538 /* BEGIN_ADMIN_LOG */
1539 sys_adminlog( LOG_ERR,
1540 "Permission denied-- user not allowed to delete, \
1541 pause, or resume print job. User name: %s. Printer name: %s.",
1542 uidtoname(user->uid), PRINTERNAME(snum) );
1543 /* END_ADMIN_LOG */
1545 return False;
1549 * get the spooled filename of the print job
1550 * if this works, then the file has not been spooled
1551 * to the underlying print system. Just delete the
1552 * spool file & return.
1555 if ( (fname = print_job_fname( snum, jobid )) != NULL )
1557 /* remove the spool file */
1558 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1559 if ( unlink( fname ) == -1 ) {
1560 *errcode = map_werror_from_unix(errno);
1561 return False;
1564 return True;
1567 if (!print_job_delete1(snum, jobid)) {
1568 *errcode = WERR_ACCESS_DENIED;
1569 return False;
1572 /* force update the database and say the delete failed if the
1573 job still exists */
1575 print_queue_update(snum);
1577 deleted = !print_job_exists(snum, jobid);
1578 if ( !deleted )
1579 *errcode = WERR_ACCESS_DENIED;
1581 return deleted;
1584 /****************************************************************************
1585 Pause a job.
1586 ****************************************************************************/
1588 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1590 struct printjob *pjob = print_job_find(snum, jobid);
1591 int ret = -1;
1593 if (!pjob || !user)
1594 return False;
1596 if (!pjob->spooled || pjob->sysjob == -1)
1597 return False;
1599 if (!is_owner(user, snum, jobid) &&
1600 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1601 DEBUG(3, ("pause denied by security descriptor\n"));
1603 /* BEGIN_ADMIN_LOG */
1604 sys_adminlog( LOG_ERR,
1605 "Permission denied-- user not allowed to delete, \
1606 pause, or resume print job. User name: %s. Printer name: %s.",
1607 uidtoname(user->uid), PRINTERNAME(snum) );
1608 /* END_ADMIN_LOG */
1610 *errcode = WERR_ACCESS_DENIED;
1611 return False;
1614 /* need to pause the spooled entry */
1615 ret = (*(current_printif->job_pause))(snum, pjob);
1617 if (ret != 0) {
1618 *errcode = WERR_INVALID_PARAM;
1619 return False;
1622 /* force update the database */
1623 print_cache_flush(snum);
1625 /* Send a printer notify message */
1627 notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1629 /* how do we tell if this succeeded? */
1631 return True;
1634 /****************************************************************************
1635 Resume a job.
1636 ****************************************************************************/
1638 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1640 struct printjob *pjob = print_job_find(snum, jobid);
1641 int ret;
1643 if (!pjob || !user)
1644 return False;
1646 if (!pjob->spooled || pjob->sysjob == -1)
1647 return False;
1649 if (!is_owner(user, snum, jobid) &&
1650 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1651 DEBUG(3, ("resume denied by security descriptor\n"));
1652 *errcode = WERR_ACCESS_DENIED;
1654 /* BEGIN_ADMIN_LOG */
1655 sys_adminlog( LOG_ERR,
1656 "Permission denied-- user not allowed to delete, \
1657 pause, or resume print job. User name: %s. Printer name: %s.",
1658 uidtoname(user->uid), PRINTERNAME(snum) );
1659 /* END_ADMIN_LOG */
1660 return False;
1663 ret = (*(current_printif->job_resume))(snum, pjob);
1665 if (ret != 0) {
1666 *errcode = WERR_INVALID_PARAM;
1667 return False;
1670 /* force update the database */
1671 print_cache_flush(snum);
1673 /* Send a printer notify message */
1675 notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1677 return True;
1680 /****************************************************************************
1681 Write to a print file.
1682 ****************************************************************************/
1684 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1686 int return_code;
1687 struct printjob *pjob = print_job_find(snum, jobid);
1689 if (!pjob)
1690 return -1;
1691 /* don't allow another process to get this info - it is meaningless */
1692 if (pjob->pid != local_pid)
1693 return -1;
1695 return_code = write(pjob->fd, buf, size);
1696 if (return_code>0) {
1697 pjob->size += size;
1698 pjob_store(snum, jobid, pjob);
1700 return return_code;
1703 /****************************************************************************
1704 Check if the print queue has been updated recently enough.
1705 ****************************************************************************/
1707 static BOOL print_cache_expired(int snum)
1709 fstring key;
1710 time_t last_qscan_time, time_now = time(NULL);
1711 const char *printername = lp_const_servicename(snum);
1712 struct tdb_print_db *pdb = get_print_db_byname(printername);
1714 if (!pdb)
1715 return False;
1717 slprintf(key, sizeof(key), "CACHE/%s", printername);
1718 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1721 * Invalidate the queue for 3 reasons.
1722 * (1). last queue scan time == -1.
1723 * (2). Current time - last queue scan time > allowed cache time.
1724 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1725 * This last test picks up machines for which the clock has been moved
1726 * forward, an lpq scan done and then the clock moved back. Otherwise
1727 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1730 if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1731 last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1732 DEBUG(3, ("print cache expired for queue %s \
1733 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1734 (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1735 release_print_db(pdb);
1736 return True;
1738 release_print_db(pdb);
1739 return False;
1742 /****************************************************************************
1743 Get the queue status - do not update if db is out of date.
1744 ****************************************************************************/
1746 static int get_queue_status(int snum, print_status_struct *status)
1748 fstring keystr;
1749 TDB_DATA data, key;
1750 const char *printername = lp_const_servicename(snum);
1751 struct tdb_print_db *pdb = get_print_db_byname(printername);
1752 int len;
1754 if (!pdb)
1755 return 0;
1757 if (status) {
1758 ZERO_STRUCTP(status);
1759 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1760 key.dptr = keystr;
1761 key.dsize = strlen(keystr);
1762 data = tdb_fetch(pdb->tdb, key);
1763 if (data.dptr) {
1764 if (data.dsize == sizeof(print_status_struct))
1765 /* this memcpy is ok since the status struct was
1766 not packed before storing it in the tdb */
1767 memcpy(status, data.dptr, sizeof(print_status_struct));
1768 SAFE_FREE(data.dptr);
1771 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1772 release_print_db(pdb);
1773 return (len == -1 ? 0 : len);
1776 /****************************************************************************
1777 Determine the number of jobs in a queue.
1778 ****************************************************************************/
1780 int print_queue_length(int snum, print_status_struct *pstatus)
1782 print_status_struct status;
1783 int len;
1785 /* make sure the database is up to date */
1786 if (print_cache_expired(snum))
1787 print_queue_update(snum);
1789 /* also fetch the queue status */
1790 memset(&status, 0, sizeof(status));
1791 len = get_queue_status(snum, &status);
1793 if (pstatus)
1794 *pstatus = status;
1796 return len;
1799 /***************************************************************************
1800 Allocate a jobid. Hold the lock for as short a time as possible.
1801 ***************************************************************************/
1803 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1805 int i;
1806 uint32 jobid;
1808 *pjobid = (uint32)-1;
1810 for (i = 0; i < 3; i++) {
1811 /* Lock the database - only wait 20 seconds. */
1812 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1813 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1814 return False;
1817 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1818 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1819 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1820 printername ));
1821 return False;
1823 jobid = 0;
1826 jobid = NEXT_JOBID(jobid);
1828 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1829 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1830 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1831 return False;
1834 /* We've finished with the INFO/nextjob lock. */
1835 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1837 if (!print_job_exists(snum, jobid))
1838 break;
1841 if (i > 2) {
1842 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1843 printername ));
1844 /* Probably full... */
1845 errno = ENOSPC;
1846 return False;
1849 /* Store a dummy placeholder. */
1851 TDB_DATA dum;
1852 dum.dptr = NULL;
1853 dum.dsize = 0;
1854 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1855 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1856 jobid ));
1857 return False;
1861 *pjobid = jobid;
1862 return True;
1865 /***************************************************************************
1866 Append a jobid to the 'jobs changed' list.
1867 ***************************************************************************/
1869 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1871 TDB_DATA data, key;
1873 key.dptr = "INFO/jobs_changed";
1874 key.dsize = strlen(key.dptr);
1875 data.dptr = (char *)&jobid;
1876 data.dsize = 4;
1878 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1880 return (tdb_append(pdb->tdb, key, data) == 0);
1883 /***************************************************************************
1884 Start spooling a job - return the jobid.
1885 ***************************************************************************/
1887 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1889 uint32 jobid;
1890 char *path;
1891 struct printjob pjob;
1892 user_struct *vuser;
1893 const char *printername = lp_const_servicename(snum);
1894 struct tdb_print_db *pdb = get_print_db_byname(printername);
1895 int njobs;
1897 errno = 0;
1899 if (!pdb)
1900 return (uint32)-1;
1902 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1903 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1904 release_print_db(pdb);
1905 return (uint32)-1;
1908 if (!print_time_access_check(snum)) {
1909 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1910 release_print_db(pdb);
1911 return (uint32)-1;
1914 path = lp_pathname(snum);
1916 /* see if we have sufficient disk space */
1917 if (lp_minprintspace(snum)) {
1918 SMB_BIG_UINT dspace, dsize;
1919 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1920 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1921 DEBUG(3, ("print_job_start: disk space check failed.\n"));
1922 release_print_db(pdb);
1923 errno = ENOSPC;
1924 return (uint32)-1;
1928 /* for autoloaded printers, check that the printcap entry still exists */
1929 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1930 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1931 release_print_db(pdb);
1932 errno = ENOENT;
1933 return (uint32)-1;
1936 /* Insure the maximum queue size is not violated */
1937 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1938 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1939 printername, njobs, lp_maxprintjobs(snum) ));
1940 release_print_db(pdb);
1941 errno = ENOSPC;
1942 return (uint32)-1;
1945 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1946 printername, njobs, lp_maxprintjobs(snum) ));
1948 if (!allocate_print_jobid(pdb, snum, printername, &jobid))
1949 goto fail;
1951 /* create the database entry */
1953 ZERO_STRUCT(pjob);
1955 pjob.pid = local_pid;
1956 pjob.sysjob = -1;
1957 pjob.fd = -1;
1958 pjob.starttime = time(NULL);
1959 pjob.status = LPQ_SPOOLING;
1960 pjob.size = 0;
1961 pjob.spooled = False;
1962 pjob.smbjob = True;
1963 pjob.nt_devmode = nt_devmode;
1965 fstrcpy(pjob.jobname, jobname);
1967 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1968 fstrcpy(pjob.user, vuser->user.smb_name);
1969 } else {
1970 fstrcpy(pjob.user, uidtoname(user->uid));
1973 fstrcpy(pjob.queuename, lp_const_servicename(snum));
1975 /* we have a job entry - now create the spool file */
1976 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
1977 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
1978 pjob.fd = smb_mkstemp(pjob.filename);
1980 if (pjob.fd == -1) {
1981 if (errno == EACCES) {
1982 /* Common setup error, force a report. */
1983 DEBUG(0, ("print_job_start: insufficient permissions \
1984 to open spool file %s.\n", pjob.filename));
1985 } else {
1986 /* Normal case, report at level 3 and above. */
1987 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1988 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1990 goto fail;
1993 pjob_store(snum, jobid, &pjob);
1995 /* Update the 'jobs changed' entry used by print_queue_status. */
1996 add_to_jobs_changed(pdb, jobid);
1998 /* Ensure we keep a rough count of the number of total jobs... */
1999 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2001 release_print_db(pdb);
2003 return jobid;
2005 fail:
2006 if (jobid != -1)
2007 pjob_delete(snum, jobid);
2009 release_print_db(pdb);
2011 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2012 return (uint32)-1;
2015 /****************************************************************************
2016 Update the number of pages spooled to jobid
2017 ****************************************************************************/
2019 void print_job_endpage(int snum, uint32 jobid)
2021 struct printjob *pjob = print_job_find(snum, jobid);
2022 if (!pjob)
2023 return;
2024 /* don't allow another process to get this info - it is meaningless */
2025 if (pjob->pid != local_pid)
2026 return;
2028 pjob->page_count++;
2029 pjob_store(snum, jobid, pjob);
2032 /****************************************************************************
2033 Print a file - called on closing the file. This spools the job.
2034 If normal close is false then we're tearing down the jobs - treat as an
2035 error.
2036 ****************************************************************************/
2038 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2040 struct printjob *pjob = print_job_find(snum, jobid);
2041 int ret;
2042 SMB_STRUCT_STAT sbuf;
2044 if (!pjob)
2045 return False;
2047 if (pjob->spooled || pjob->pid != local_pid)
2048 return False;
2050 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2051 pjob->size = sbuf.st_size;
2052 close(pjob->fd);
2053 pjob->fd = -1;
2054 } else {
2057 * Not a normal close or we couldn't stat the job file,
2058 * so something has gone wrong. Cleanup.
2060 close(pjob->fd);
2061 pjob->fd = -1;
2062 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2063 goto fail;
2066 /* Technically, this is not quite right. If the printer has a separator
2067 * page turned on, the NT spooler prints the separator page even if the
2068 * print job is 0 bytes. 010215 JRR */
2069 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2070 /* don't bother spooling empty files or something being deleted. */
2071 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2072 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2073 unlink(pjob->filename);
2074 pjob_delete(snum, jobid);
2075 return True;
2078 pjob->smbjob = jobid;
2080 ret = (*(current_printif->job_submit))(snum, pjob);
2082 if (ret)
2083 goto fail;
2085 /* The print job has been sucessfully handed over to the back-end */
2087 pjob->spooled = True;
2088 pjob->status = LPQ_QUEUED;
2089 pjob_store(snum, jobid, pjob);
2091 /* make sure the database is up to date */
2092 if (print_cache_expired(snum))
2093 print_queue_update(snum);
2095 return True;
2097 fail:
2099 /* The print job was not succesfully started. Cleanup */
2100 /* Still need to add proper error return propagation! 010122:JRR */
2101 unlink(pjob->filename);
2102 pjob_delete(snum, jobid);
2103 remove_from_jobs_changed(snum, jobid);
2104 return False;
2107 /****************************************************************************
2108 Get a snapshot of jobs in the system without traversing.
2109 ****************************************************************************/
2111 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2113 TDB_DATA data, key, cgdata;
2114 print_queue_struct *queue = NULL;
2115 uint32 qcount = 0;
2116 uint32 extra_count = 0;
2117 int total_count = 0;
2118 size_t len = 0;
2119 uint32 i;
2120 int max_reported_jobs = lp_max_reported_jobs(snum);
2121 BOOL ret = False;
2123 /* make sure the database is up to date */
2124 if (print_cache_expired(snum))
2125 print_queue_update(snum);
2127 *pcount = 0;
2128 *ppqueue = NULL;
2130 ZERO_STRUCT(data);
2131 ZERO_STRUCT(cgdata);
2132 key.dptr = "INFO/linear_queue_array";
2133 key.dsize = strlen(key.dptr);
2135 /* Get the stored queue data. */
2136 data = tdb_fetch(pdb->tdb, key);
2138 if (data.dptr && data.dsize >= sizeof(qcount))
2139 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2141 /* Get the changed jobs list. */
2142 key.dptr = "INFO/jobs_changed";
2143 key.dsize = strlen(key.dptr);
2145 cgdata = tdb_fetch(pdb->tdb, key);
2146 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2147 extra_count = cgdata.dsize/4;
2149 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2151 /* Allocate the queue size. */
2152 if (qcount == 0 && extra_count == 0)
2153 goto out;
2155 if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2156 goto out;
2158 /* Retrieve the linearised queue data. */
2160 for( i = 0; i < qcount; i++) {
2161 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2162 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2163 &qjob,
2164 &qsize,
2165 &qpage_count,
2166 &qstatus,
2167 &qpriority,
2168 &qtime,
2169 queue[i].fs_user,
2170 queue[i].fs_file);
2171 queue[i].job = qjob;
2172 queue[i].size = qsize;
2173 queue[i].page_count = qpage_count;
2174 queue[i].status = qstatus;
2175 queue[i].priority = qpriority;
2176 queue[i].time = qtime;
2179 total_count = qcount;
2181 /* Add in the changed jobids. */
2182 for( i = 0; i < extra_count; i++) {
2183 uint32 jobid;
2184 struct printjob *pjob;
2186 jobid = IVAL(&cgdata.dptr, i*4);
2187 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2188 pjob = print_job_find(snum, jobid);
2189 if (!pjob) {
2190 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2191 remove_from_jobs_changed(snum, jobid);
2192 continue;
2195 queue[total_count].job = jobid;
2196 queue[total_count].size = pjob->size;
2197 queue[total_count].page_count = pjob->page_count;
2198 queue[total_count].status = pjob->status;
2199 queue[total_count].priority = 1;
2200 queue[total_count].time = pjob->starttime;
2201 fstrcpy(queue[total_count].fs_user, pjob->user);
2202 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2203 total_count++;
2206 /* Sort the queue by submission time otherwise they are displayed
2207 in hash order. */
2209 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2211 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2213 if (max_reported_jobs && total_count > max_reported_jobs)
2214 total_count = max_reported_jobs;
2216 *ppqueue = queue;
2217 *pcount = total_count;
2219 ret = True;
2221 out:
2223 SAFE_FREE(data.dptr);
2224 SAFE_FREE(cgdata.dptr);
2225 return ret;
2228 /****************************************************************************
2229 Get a printer queue listing.
2230 set queue = NULL and status = NULL if you just want to update the cache
2231 ****************************************************************************/
2233 int print_queue_status(int snum,
2234 print_queue_struct **ppqueue,
2235 print_status_struct *status)
2237 fstring keystr;
2238 TDB_DATA data, key;
2239 const char *printername;
2240 struct tdb_print_db *pdb;
2241 int count = 0;
2243 /* make sure the database is up to date */
2245 if (print_cache_expired(snum))
2246 print_queue_update(snum);
2248 /* return if we are done */
2249 if ( !ppqueue || !status )
2250 return 0;
2252 *ppqueue = NULL;
2253 printername = lp_const_servicename(snum);
2254 pdb = get_print_db_byname(printername);
2256 if (!pdb)
2257 return 0;
2260 * Fetch the queue status. We must do this first, as there may
2261 * be no jobs in the queue.
2264 ZERO_STRUCTP(status);
2265 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2266 key.dptr = keystr;
2267 key.dsize = strlen(keystr);
2268 data = tdb_fetch(pdb->tdb, key);
2269 if (data.dptr) {
2270 if (data.dsize == sizeof(*status)) {
2271 /* this memcpy is ok since the status struct was
2272 not packed before storing it in the tdb */
2273 memcpy(status, data.dptr, sizeof(*status));
2275 SAFE_FREE(data.dptr);
2279 * Now, fetch the print queue information. We first count the number
2280 * of entries, and then only retrieve the queue if necessary.
2283 if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2284 release_print_db(pdb);
2285 return 0;
2288 release_print_db(pdb);
2289 return count;
2292 /****************************************************************************
2293 Pause a queue.
2294 ****************************************************************************/
2296 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2298 int ret;
2300 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2301 *errcode = WERR_ACCESS_DENIED;
2302 return False;
2305 ret = (*(current_printif->queue_pause))(snum);
2307 if (ret != 0) {
2308 *errcode = WERR_INVALID_PARAM;
2309 return False;
2312 /* force update the database */
2313 print_cache_flush(snum);
2315 /* Send a printer notify message */
2317 notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2319 return True;
2322 /****************************************************************************
2323 Resume a queue.
2324 ****************************************************************************/
2326 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2328 int ret;
2330 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2331 *errcode = WERR_ACCESS_DENIED;
2332 return False;
2335 ret = (*(current_printif->queue_resume))(snum);
2337 if (ret != 0) {
2338 *errcode = WERR_INVALID_PARAM;
2339 return False;
2342 /* make sure the database is up to date */
2343 if (print_cache_expired(snum))
2344 print_queue_update(snum);
2346 /* Send a printer notify message */
2348 notify_printer_status(snum, PRINTER_STATUS_OK);
2350 return True;
2353 /****************************************************************************
2354 Purge a queue - implemented by deleting all jobs that we can delete.
2355 ****************************************************************************/
2357 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2359 print_queue_struct *queue;
2360 print_status_struct status;
2361 int njobs, i;
2362 BOOL can_job_admin;
2364 /* Force and update so the count is accurate (i.e. not a cached count) */
2365 print_queue_update(snum);
2367 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2368 njobs = print_queue_status(snum, &queue, &status);
2370 for (i=0;i<njobs;i++) {
2371 BOOL owner = is_owner(user, snum, queue[i].job);
2373 if (owner || can_job_admin) {
2374 print_job_delete1(snum, queue[i].job);
2378 SAFE_FREE(queue);
2380 return True;