4ff9b6b91270132aea5db7b0f7f59972bb7bec52
[samba.git] / source / printing / printing.c
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
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24 #include "printing.h"
25
26 extern SIG_ATOMIC_T got_sig_term;
27 extern SIG_ATOMIC_T reload_after_sighup;
28 extern struct current_user current_user;
29 extern userdom_struct current_user_info;
30
31 /* Current printer interface */
32 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
33
34 /* 
35    the printing backend revolves around a tdb database that stores the
36    SMB view of the print queue 
37    
38    The key for this database is a jobid - a internally generated number that
39    uniquely identifies a print job
40
41    reading the print queue involves two steps:
42      - possibly running lpq and updating the internal database from that
43      - reading entries from the database
44
45    jobids are assigned when a job starts spooling. 
46 */
47
48 static TDB_CONTEXT *rap_tdb;
49 static uint16 next_rap_jobid;
50 struct rap_jobid_key {
51         fstring sharename;
52         uint32  jobid;
53 };
54
55 /***************************************************************************
56  Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
57  bit RPC jobids.... JRA.
58 ***************************************************************************/
59
60 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
61 {
62         uint16 rap_jobid;
63         TDB_DATA data, key;
64         struct rap_jobid_key jinfo;
65         uint8 buf[2];
66
67         DEBUG(10,("pjobid_to_rap: called.\n"));
68
69         if (!rap_tdb) {
70                 /* Create the in-memory tdb. */
71                 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
72                 if (!rap_tdb)
73                         return 0;
74         }
75
76         ZERO_STRUCT( jinfo );
77         fstrcpy( jinfo.sharename, sharename );
78         jinfo.jobid = jobid;
79         key.dptr = (char*)&jinfo;
80         key.dsize = sizeof(jinfo);
81
82         data = tdb_fetch(rap_tdb, key);
83         if (data.dptr && data.dsize == sizeof(uint16)) {
84                 rap_jobid = SVAL(data.dptr, 0);
85                 SAFE_FREE(data.dptr);
86                 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
87                         (unsigned int)jobid, (unsigned int)rap_jobid));
88                 return rap_jobid;
89         }
90         SAFE_FREE(data.dptr);
91         /* Not found - create and store mapping. */
92         rap_jobid = ++next_rap_jobid;
93         if (rap_jobid == 0)
94                 rap_jobid = ++next_rap_jobid;
95         SSVAL(buf,0,rap_jobid);
96         data.dptr = (char*)buf;
97         data.dsize = sizeof(rap_jobid);
98         tdb_store(rap_tdb, key, data, TDB_REPLACE);
99         tdb_store(rap_tdb, data, key, TDB_REPLACE);
100
101         DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
102                 (unsigned int)jobid, (unsigned int)rap_jobid));
103         return rap_jobid;
104 }
105
106 BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
107 {
108         TDB_DATA data, key;
109         uint8 buf[2];
110
111         DEBUG(10,("rap_to_pjobid called.\n"));
112
113         if (!rap_tdb)
114                 return False;
115
116         SSVAL(buf,0,rap_jobid);
117         key.dptr = (char*)buf;
118         key.dsize = sizeof(rap_jobid);
119         data = tdb_fetch(rap_tdb, key);
120         if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) 
121         {
122                 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
123                 fstrcpy( sharename, jinfo->sharename );
124                 *pjobid = jinfo->jobid;
125                 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
126                         (unsigned int)*pjobid, (unsigned int)rap_jobid));
127                 SAFE_FREE(data.dptr);
128                 return True;
129         }
130
131         DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
132                 (unsigned int)rap_jobid));
133         SAFE_FREE(data.dptr);
134         return False;
135 }
136
137 static void rap_jobid_delete(const char* sharename, uint32 jobid)
138 {
139         TDB_DATA key, data;
140         uint16 rap_jobid;
141         struct rap_jobid_key jinfo;
142         uint8 buf[2];
143
144         DEBUG(10,("rap_jobid_delete: called.\n"));
145
146         if (!rap_tdb)
147                 return;
148
149         ZERO_STRUCT( jinfo );
150         fstrcpy( jinfo.sharename, sharename );
151         jinfo.jobid = jobid;
152         key.dptr = (char*)&jinfo;
153         key.dsize = sizeof(jinfo);
154
155         data = tdb_fetch(rap_tdb, key);
156         if (!data.dptr || (data.dsize != sizeof(uint16))) {
157                 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
158                         (unsigned int)jobid ));
159                 SAFE_FREE(data.dptr);
160                 return;
161         }
162
163         DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
164                 (unsigned int)jobid ));
165
166         rap_jobid = SVAL(data.dptr, 0);
167         SAFE_FREE(data.dptr);
168         SSVAL(buf,0,rap_jobid);
169         data.dptr = (char*)buf;
170         data.dsize = sizeof(rap_jobid);
171         tdb_delete(rap_tdb, key);
172         tdb_delete(rap_tdb, data);
173 }
174
175 static int get_queue_status(const char* sharename, print_status_struct *);
176
177 /****************************************************************************
178  Initialise the printing backend. Called once at startup before the fork().
179 ****************************************************************************/
180
181 BOOL print_backend_init(void)
182 {
183         const char *sversion = "INFO/version";
184         pstring printing_path;
185         int services = lp_numservices();
186         int snum;
187
188         unlink(lock_path("printing.tdb"));
189         pstrcpy(printing_path,lock_path("printing"));
190         mkdir(printing_path,0755);
191
192         /* handle a Samba upgrade */
193
194         for (snum = 0; snum < services; snum++) {
195                 struct tdb_print_db *pdb;
196                 if (!lp_print_ok(snum))
197                         continue;
198
199                 pdb = get_print_db_byname(lp_const_servicename(snum));
200                 if (!pdb)
201                         continue;
202                 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
203                         DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
204                         release_print_db(pdb);
205                         return False;
206                 }
207                 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
208                         tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
209                         tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
210                 }
211                 tdb_unlock_bystring(pdb->tdb, sversion);
212                 release_print_db(pdb);
213         }
214
215         close_all_print_db(); /* Don't leave any open. */
216
217         /* do NT print initialization... */
218         return nt_printing_init();
219 }
220
221 /****************************************************************************
222  Shut down printing backend. Called once at shutdown to close the tdb.
223 ****************************************************************************/
224
225 void printing_end(void)
226 {
227         close_all_print_db(); /* Don't leave any open. */
228 }
229
230 /****************************************************************************
231  Retrieve the set of printing functions for a given service.  This allows 
232  us to set the printer function table based on the value of the 'printing'
233  service parameter.
234  
235  Use the generic interface as the default and only use cups interface only
236  when asked for (and only when supported)
237 ****************************************************************************/
238
239 static struct printif *get_printer_fns_from_type( enum printing_types type )
240 {
241         struct printif *printer_fns = &generic_printif;
242
243 #ifdef HAVE_CUPS
244         if ( type == PRINT_CUPS ) {
245                 printer_fns = &cups_printif;
246         }
247 #endif /* HAVE_CUPS */
248
249 #ifdef HAVE_IPRINT
250         if ( type == PRINT_IPRINT ) {
251                 printer_fns = &iprint_printif;
252         }
253 #endif /* HAVE_IPRINT */
254
255         printer_fns->type = type;
256         
257         return printer_fns;
258 }
259
260 static struct printif *get_printer_fns( int snum )
261 {
262         return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
263 }
264
265
266 /****************************************************************************
267  Useful function to generate a tdb key.
268 ****************************************************************************/
269
270 static TDB_DATA print_key(uint32 jobid)
271 {
272         static uint32 j;
273         TDB_DATA ret;
274
275         SIVAL(&j, 0, jobid);
276         ret.dptr = (char *)&j;
277         ret.dsize = sizeof(j);
278         return ret;
279 }
280
281 /***********************************************************************
282  unpack a pjob from a tdb buffer 
283 ***********************************************************************/
284  
285 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
286 {
287         int     len = 0;
288         int     used;
289         uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
290         uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
291
292         if ( !buf || !pjob )
293                 return -1;
294                 
295         len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
296                                 &pjpid,
297                                 &pjsysjob,
298                                 &pjfd,
299                                 &pjstarttime,
300                                 &pjstatus,
301                                 &pjsize,
302                                 &pjpage_count,
303                                 &pjspooled,
304                                 &pjsmbjob,
305                                 pjob->filename,
306                                 pjob->jobname,
307                                 pjob->user,
308                                 pjob->queuename);
309                                 
310         if ( len == -1 )
311                 return -1;
312                 
313         if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
314                 return -1;
315         
316         len += used;
317
318         pjob->pid = pjpid;
319         pjob->sysjob = pjsysjob;
320         pjob->fd = pjfd;
321         pjob->starttime = pjstarttime;
322         pjob->status = pjstatus;
323         pjob->size = pjsize;
324         pjob->page_count = pjpage_count;
325         pjob->spooled = pjspooled;
326         pjob->smbjob = pjsmbjob;
327         
328         return len;
329
330 }
331
332 /****************************************************************************
333  Useful function to find a print job in the database.
334 ****************************************************************************/
335
336 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
337 {
338         static struct printjob  pjob;
339         TDB_DATA                ret;
340         struct tdb_print_db     *pdb = get_print_db_byname(sharename);
341         
342         DEBUG(10,("print_job_find: looking up job %u for share %s\n",
343                         (unsigned int)jobid, sharename ));
344
345         if (!pdb) {
346                 return NULL;
347         }
348
349         ret = tdb_fetch(pdb->tdb, print_key(jobid));
350         release_print_db(pdb);
351
352         if (!ret.dptr) {
353                 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
354                 return NULL;
355         }
356         
357         if ( pjob.nt_devmode ) {
358                 free_nt_devicemode( &pjob.nt_devmode );
359         }
360                 
361         ZERO_STRUCT( pjob );
362         
363         if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
364                 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
365                 SAFE_FREE(ret.dptr);
366                 return NULL;
367         }
368         
369         SAFE_FREE(ret.dptr);
370
371         DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
372                         (int)pjob.sysjob, (unsigned int)jobid ));
373
374         return &pjob;
375 }
376
377 /* Convert a unix jobid to a smb jobid */
378
379 static uint32 sysjob_to_jobid_value;
380
381 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
382                                TDB_DATA data, void *state)
383 {
384         struct printjob *pjob;
385         int *sysjob = (int *)state;
386
387         if (!data.dptr || data.dsize == 0)
388                 return 0;
389
390         pjob = (struct printjob *)data.dptr;
391         if (key.dsize != sizeof(uint32))
392                 return 0;
393
394         if (*sysjob == pjob->sysjob) {
395                 uint32 jobid = IVAL(key.dptr,0);
396
397                 sysjob_to_jobid_value = jobid;
398                 return 1;
399         }
400
401         return 0;
402 }
403
404 /****************************************************************************
405  This is a *horribly expensive call as we have to iterate through all the
406  current printer tdb's. Don't do this often ! JRA.
407 ****************************************************************************/
408
409 uint32 sysjob_to_jobid(int unix_jobid)
410 {
411         int services = lp_numservices();
412         int snum;
413
414         sysjob_to_jobid_value = (uint32)-1;
415
416         for (snum = 0; snum < services; snum++) {
417                 struct tdb_print_db *pdb;
418                 if (!lp_print_ok(snum))
419                         continue;
420                 pdb = get_print_db_byname(lp_const_servicename(snum));
421                 if (!pdb) {
422                         continue;
423                 }
424                 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
425                 release_print_db(pdb);
426                 if (sysjob_to_jobid_value != (uint32)-1)
427                         return sysjob_to_jobid_value;
428         }
429         return (uint32)-1;
430 }
431
432 /****************************************************************************
433  Send notifications based on what has changed after a pjob_store.
434 ****************************************************************************/
435
436 static struct {
437         uint32 lpq_status;
438         uint32 spoolss_status;
439 } lpq_to_spoolss_status_map[] = {
440         { LPQ_QUEUED, JOB_STATUS_QUEUED },
441         { LPQ_PAUSED, JOB_STATUS_PAUSED },
442         { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
443         { LPQ_PRINTING, JOB_STATUS_PRINTING },
444         { LPQ_DELETING, JOB_STATUS_DELETING },
445         { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
446         { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
447         { LPQ_PRINTED, JOB_STATUS_PRINTED },
448         { LPQ_DELETED, JOB_STATUS_DELETED },
449         { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
450         { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
451         { -1, 0 }
452 };
453
454 /* Convert a lpq status value stored in printing.tdb into the
455    appropriate win32 API constant. */
456
457 static uint32 map_to_spoolss_status(uint32 lpq_status)
458 {
459         int i = 0;
460
461         while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
462                 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
463                         return lpq_to_spoolss_status_map[i].spoolss_status;
464                 i++;
465         }
466
467         return 0;
468 }
469
470 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
471                               struct printjob *new_data)
472 {
473         BOOL new_job = False;
474
475         if (!old_data)
476                 new_job = True;
477
478         /* Job attributes that can't be changed.  We only send
479            notification for these on a new job. */
480
481         /* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the 
482            NOTIFY_INFO_DATA buffer, we *have* to send the job submission 
483            time first or else we'll end up with potential alignment 
484            errors.  I don't think the systemtime should be spooled as 
485            a string, but this gets us around that error.   
486            --jerry (i'll feel dirty for this) */
487  
488         if (new_job) {
489                 notify_job_submitted(sharename, jobid, new_data->starttime);
490                 notify_job_username(sharename, jobid, new_data->user);
491         }
492
493         if (new_job || !strequal(old_data->jobname, new_data->jobname))
494                 notify_job_name(sharename, jobid, new_data->jobname);
495
496         /* Job attributes of a new job or attributes that can be
497            modified. */
498
499         if (new_job || !strequal(old_data->jobname, new_data->jobname))
500                 notify_job_name(sharename, jobid, new_data->jobname);
501
502         if (new_job || old_data->status != new_data->status)
503                 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
504
505         if (new_job || old_data->size != new_data->size)
506                 notify_job_total_bytes(sharename, jobid, new_data->size);
507
508         if (new_job || old_data->page_count != new_data->page_count)
509                 notify_job_total_pages(sharename, jobid, new_data->page_count);
510 }
511
512 /****************************************************************************
513  Store a job structure back to the database.
514 ****************************************************************************/
515
516 static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
517 {
518         TDB_DATA                old_data, new_data;
519         BOOL                    ret = False;
520         struct tdb_print_db     *pdb = get_print_db_byname(sharename);
521         char                    *buf = NULL;
522         int                     len, newlen, buflen;
523         
524
525         if (!pdb)
526                 return False;
527
528         /* Get old data */
529
530         old_data = tdb_fetch(pdb->tdb, print_key(jobid));
531
532         /* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
533
534         newlen = 0;
535         
536         do {
537                 len = 0;
538                 buflen = newlen;
539                 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
540                                 (uint32)pjob->pid,
541                                 (uint32)pjob->sysjob,
542                                 (uint32)pjob->fd,
543                                 (uint32)pjob->starttime,
544                                 (uint32)pjob->status,
545                                 (uint32)pjob->size,
546                                 (uint32)pjob->page_count,
547                                 (uint32)pjob->spooled,
548                                 (uint32)pjob->smbjob,
549                                 pjob->filename,
550                                 pjob->jobname,
551                                 pjob->user,
552                                 pjob->queuename);
553
554                 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
555         
556                 if (buflen != len) {
557                         buf = (char *)SMB_REALLOC(buf, len);
558                         if (!buf) {
559                                 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
560                                 goto done;
561                         }
562                         newlen = len;
563                 }
564         } while ( buflen != len );
565                 
566         
567         /* Store new data */
568
569         new_data.dptr = buf;
570         new_data.dsize = len;
571         ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
572
573         release_print_db(pdb);
574
575         /* Send notify updates for what has changed */
576
577         if ( ret ) {
578                 struct printjob old_pjob;
579
580                 if ( old_data.dsize )
581                 {
582                         if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
583                         {
584                                 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
585                                 free_nt_devicemode( &old_pjob.nt_devmode );
586                         }
587                 }
588                 else {
589                         /* new job */
590                         pjob_store_notify( sharename, jobid, NULL, pjob );
591                 }
592         }
593
594 done:
595         SAFE_FREE( old_data.dptr );
596         SAFE_FREE( buf );
597
598         return ret;
599 }
600
601 /****************************************************************************
602  Remove a job structure from the database.
603 ****************************************************************************/
604
605 void pjob_delete(const char* sharename, uint32 jobid)
606 {
607         struct printjob *pjob;
608         uint32 job_status = 0;
609         struct tdb_print_db *pdb;
610
611         pdb = get_print_db_byname( sharename );
612
613         if (!pdb)
614                 return;
615
616         pjob = print_job_find( sharename, jobid );
617
618         if (!pjob) {
619                 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
620                                         (unsigned int)jobid));
621                 release_print_db(pdb);
622                 return;
623         }
624
625         /* We must cycle through JOB_STATUS_DELETING and
626            JOB_STATUS_DELETED for the port monitor to delete the job
627            properly. */
628         
629         job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
630         notify_job_status(sharename, jobid, job_status);
631         
632         /* Remove from printing.tdb */
633
634         tdb_delete(pdb->tdb, print_key(jobid));
635         remove_from_jobs_changed(sharename, jobid);
636         release_print_db( pdb );
637         rap_jobid_delete(sharename, jobid);
638 }
639
640 /****************************************************************************
641  Parse a file name from the system spooler to generate a jobid.
642 ****************************************************************************/
643
644 static uint32 print_parse_jobid(char *fname)
645 {
646         int jobid;
647
648         if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
649                 return (uint32)-1;
650         fname += strlen(PRINT_SPOOL_PREFIX);
651
652         jobid = atoi(fname);
653         if (jobid <= 0)
654                 return (uint32)-1;
655
656         return (uint32)jobid;
657 }
658
659 /****************************************************************************
660  List a unix job in the print database.
661 ****************************************************************************/
662
663 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
664 {
665         struct printjob pj, *old_pj;
666
667         if (jobid == (uint32)-1) 
668                 jobid = q->job + UNIX_JOB_START;
669
670         /* Preserve the timestamp on an existing unix print job */
671
672         old_pj = print_job_find(sharename, jobid);
673
674         ZERO_STRUCT(pj);
675
676         pj.pid = (pid_t)-1;
677         pj.sysjob = q->job;
678         pj.fd = -1;
679         pj.starttime = old_pj ? old_pj->starttime : q->time;
680         pj.status = q->status;
681         pj.size = q->size;
682         pj.spooled = True;
683         fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
684         if (jobid < UNIX_JOB_START) {
685                 pj.smbjob = True;
686                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
687         } else {
688                 pj.smbjob = False;
689                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
690         }
691         fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
692         fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
693
694         pjob_store(sharename, jobid, &pj);
695 }
696
697
698 struct traverse_struct {
699         print_queue_struct *queue;
700         int qcount, snum, maxcount, total_jobs;
701         const char *sharename;
702         time_t lpq_time;
703         const char *lprm_command;
704         struct printif *print_if;
705 };
706
707 /****************************************************************************
708  Utility fn to delete any jobs that are no longer active.
709 ****************************************************************************/
710
711 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
712 {
713         struct traverse_struct *ts = (struct traverse_struct *)state;
714         struct printjob pjob;
715         uint32 jobid;
716         int i = 0;
717
718         if (  key.dsize != sizeof(jobid) )
719                 return 0;
720                 
721         jobid = IVAL(key.dptr, 0);
722         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
723                 return 0;
724         free_nt_devicemode( &pjob.nt_devmode );
725
726
727         if (!pjob.smbjob) {
728                 /* remove a unix job if it isn't in the system queue any more */
729
730                 for (i=0;i<ts->qcount;i++) {
731                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
732                         if (jobid == u_jobid)
733                                 break;
734                 }
735                 if (i == ts->qcount) {
736                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
737                                                 (unsigned int)jobid ));
738                         pjob_delete(ts->sharename, jobid);
739                         return 0;
740                 } 
741
742                 /* need to continue the the bottom of the function to
743                    save the correct attributes */
744         }
745
746         /* maybe it hasn't been spooled yet */
747         if (!pjob.spooled) {
748                 /* if a job is not spooled and the process doesn't
749                    exist then kill it. This cleans up after smbd
750                    deaths */
751                 if (!process_exists_by_pid(pjob.pid)) {
752                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
753                                                 (unsigned int)jobid, (unsigned int)pjob.pid ));
754                         pjob_delete(ts->sharename, jobid);
755                 } else
756                         ts->total_jobs++;
757                 return 0;
758         }
759
760         /* this check only makes sense for jobs submitted from Windows clients */
761         
762         if ( pjob.smbjob ) {
763                 for (i=0;i<ts->qcount;i++) {
764                         uint32 curr_jobid;
765
766                         if ( pjob.status == LPQ_DELETED )
767                                 continue;
768
769                         curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
770
771                         if (jobid == curr_jobid) {
772
773                                 /* try to clean up any jobs that need to be deleted */
774
775                                 if ( pjob.status == LPQ_DELETING ) {
776                                         int result;
777
778                                         result = (*(ts->print_if->job_delete))( 
779                                                 ts->sharename, ts->lprm_command, &pjob );
780
781                                         if ( result != 0 ) {
782                                                 /* if we can't delete, then reset the job status */
783                                                 pjob.status = LPQ_QUEUED;
784                                                 pjob_store(ts->sharename, jobid, &pjob);
785                                         }
786                                         else {
787                                                 /* if we deleted the job, the remove the tdb record */
788                                                 pjob_delete(ts->sharename, jobid);
789                                                 pjob.status = LPQ_DELETED;
790                                         }
791                                                 
792                                 }
793
794                                 break;
795                         }
796                 }
797         }
798         
799         /* The job isn't in the system queue - we have to assume it has
800            completed, so delete the database entry. */
801
802         if (i == ts->qcount) {
803
804                 /* A race can occur between the time a job is spooled and
805                    when it appears in the lpq output.  This happens when
806                    the job is added to printing.tdb when another smbd
807                    running print_queue_update() has completed a lpq and
808                    is currently traversing the printing tdb and deleting jobs.
809                    Don't delete the job if it was submitted after the lpq_time. */
810
811                 if (pjob.starttime < ts->lpq_time) {
812                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
813                                                 (unsigned int)jobid,
814                                                 (unsigned int)pjob.starttime,
815                                                 (unsigned int)ts->lpq_time ));
816                         pjob_delete(ts->sharename, jobid);
817                 } else
818                         ts->total_jobs++;
819                 return 0;
820         }
821
822         /* Save the pjob attributes we will store. 
823            FIXME!!! This is the only place where queue->job 
824            represents the SMB jobid      --jerry */
825
826         ts->queue[i].job = jobid;               
827         ts->queue[i].size = pjob.size;
828         ts->queue[i].page_count = pjob.page_count;
829         ts->queue[i].status = pjob.status;
830         ts->queue[i].priority = 1;
831         ts->queue[i].time = pjob.starttime;
832         fstrcpy(ts->queue[i].fs_user, pjob.user);
833         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
834
835         ts->total_jobs++;
836
837         return 0;
838 }
839
840 /****************************************************************************
841  Check if the print queue has been updated recently enough.
842 ****************************************************************************/
843
844 static void print_cache_flush(const char *sharename)
845 {
846         fstring key;
847         struct tdb_print_db *pdb = get_print_db_byname(sharename);
848
849         if (!pdb)
850                 return;
851         slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
852         tdb_store_int32(pdb->tdb, key, -1);
853         release_print_db(pdb);
854 }
855
856 /****************************************************************************
857  Check if someone already thinks they are doing the update.
858 ****************************************************************************/
859
860 static pid_t get_updating_pid(const char *sharename)
861 {
862         fstring keystr;
863         TDB_DATA data, key;
864         pid_t updating_pid;
865         struct tdb_print_db *pdb = get_print_db_byname(sharename);
866
867         if (!pdb)
868                 return (pid_t)-1;
869         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
870         key.dptr = keystr;
871         key.dsize = strlen(keystr);
872
873         data = tdb_fetch(pdb->tdb, key);
874         release_print_db(pdb);
875         if (!data.dptr || data.dsize != sizeof(pid_t)) {
876                 SAFE_FREE(data.dptr);
877                 return (pid_t)-1;
878         }
879
880         updating_pid = IVAL(data.dptr, 0);
881         SAFE_FREE(data.dptr);
882
883         if (process_exists_by_pid(updating_pid))
884                 return updating_pid;
885
886         return (pid_t)-1;
887 }
888
889 /****************************************************************************
890  Set the fact that we're doing the update, or have finished doing the update
891  in the tdb.
892 ****************************************************************************/
893
894 static void set_updating_pid(const fstring sharename, BOOL updating)
895 {
896         fstring keystr;
897         TDB_DATA key;
898         TDB_DATA data;
899         pid_t updating_pid = sys_getpid();
900         uint8 buffer[4];
901         
902         struct tdb_print_db *pdb = get_print_db_byname(sharename);
903
904         if (!pdb)
905                 return;
906
907         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
908         key.dptr = keystr;
909         key.dsize = strlen(keystr);
910         
911         DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", 
912                 updating ? "" : "not ",
913                 sharename ));
914
915         if ( !updating ) {
916                 tdb_delete(pdb->tdb, key);
917                 release_print_db(pdb);
918                 return;
919         }
920         
921         SIVAL( buffer, 0, updating_pid);
922         data.dptr = (char *)buffer;
923         data.dsize = 4;         /* we always assume this is a 4 byte value */
924
925         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
926         release_print_db(pdb);
927 }
928
929 /****************************************************************************
930  Sort print jobs by submittal time.
931 ****************************************************************************/
932
933 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
934 {
935         /* Silly cases */
936
937         if (!j1 && !j2)
938                 return 0;
939         if (!j1)
940                 return -1;
941         if (!j2)
942                 return 1;
943
944         /* Sort on job start time */
945
946         if (j1->time == j2->time)
947                 return 0;
948         return (j1->time > j2->time) ? 1 : -1;
949 }
950
951 /****************************************************************************
952  Store the sorted queue representation for later portmon retrieval.
953  Skip deleted jobs
954 ****************************************************************************/
955
956 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
957 {
958         TDB_DATA data;
959         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
960         print_queue_struct *queue = pts->queue;
961         size_t len;
962         size_t i;
963         uint qcount;
964
965         if (max_reported_jobs && (max_reported_jobs < pts->qcount))
966                 pts->qcount = max_reported_jobs;
967         qcount = 0;
968
969         /* Work out the size. */
970         data.dsize = 0;
971         data.dsize += tdb_pack(NULL, 0, "d", qcount);
972
973         for (i = 0; i < pts->qcount; i++) {
974                 if ( queue[i].status == LPQ_DELETED )
975                         continue;
976
977                 qcount++;
978                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
979                                 (uint32)queue[i].job,
980                                 (uint32)queue[i].size,
981                                 (uint32)queue[i].page_count,
982                                 (uint32)queue[i].status,
983                                 (uint32)queue[i].priority,
984                                 (uint32)queue[i].time,
985                                 queue[i].fs_user,
986                                 queue[i].fs_file);
987         }
988
989         if ((data.dptr = (char *)SMB_MALLOC(data.dsize)) == NULL)
990                 return;
991
992         len = 0;
993         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
994         for (i = 0; i < pts->qcount; i++) {
995                 if ( queue[i].status == LPQ_DELETED )
996                         continue;
997
998                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
999                                 (uint32)queue[i].job,
1000                                 (uint32)queue[i].size,
1001                                 (uint32)queue[i].page_count,
1002                                 (uint32)queue[i].status,
1003                                 (uint32)queue[i].priority,
1004                                 (uint32)queue[i].time,
1005                                 queue[i].fs_user,
1006                                 queue[i].fs_file);
1007         }
1008
1009         tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1010                   TDB_REPLACE);
1011         SAFE_FREE(data.dptr);
1012         return;
1013 }
1014
1015 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1016 {
1017         TDB_DATA data;
1018
1019         ZERO_STRUCT(data);
1020
1021         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1022         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1023                 SAFE_FREE(data.dptr);
1024                 ZERO_STRUCT(data);
1025         }
1026
1027         return data;
1028 }
1029
1030 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1031 {
1032         unsigned int i;
1033         unsigned int job_count = data.dsize / 4;
1034
1035         for (i = 0; i < job_count; i++) {
1036                 uint32 ch_jobid;
1037
1038                 ch_jobid = IVAL(data.dptr, i*4);
1039                 if (ch_jobid == jobid)
1040                         remove_from_jobs_changed(sharename, jobid);
1041         }
1042 }
1043
1044 /****************************************************************************
1045  Check if the print queue has been updated recently enough.
1046 ****************************************************************************/
1047
1048 static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
1049 {
1050         fstring key;
1051         time_t last_qscan_time, time_now = time(NULL);
1052         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1053         BOOL result = False;
1054
1055         if (!pdb)
1056                 return False;
1057
1058         snprintf(key, sizeof(key), "CACHE/%s", sharename);
1059         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1060
1061         /*
1062          * Invalidate the queue for 3 reasons.
1063          * (1). last queue scan time == -1.
1064          * (2). Current time - last queue scan time > allowed cache time.
1065          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1066          * This last test picks up machines for which the clock has been moved
1067          * forward, an lpq scan done and then the clock moved back. Otherwise
1068          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1069          */
1070
1071         if (last_qscan_time == ((time_t)-1) 
1072                 || (time_now - last_qscan_time) >= lp_lpqcachetime() 
1073                 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) 
1074         {
1075                 uint32 u;
1076                 time_t msg_pending_time;
1077
1078                 DEBUG(4, ("print_cache_expired: cache expired for queue %s " 
1079                         "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", 
1080                         sharename, (int)last_qscan_time, (int)time_now, 
1081                         (int)lp_lpqcachetime() ));
1082
1083                 /* check if another smbd has already sent a message to update the 
1084                    queue.  Give the pending message one minute to clear and 
1085                    then send another message anyways.  Make sure to check for 
1086                    clocks that have been run forward and then back again. */
1087
1088                 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1089
1090                 if ( check_pending 
1091                         && tdb_fetch_uint32( pdb->tdb, key, &u ) 
1092                         && (msg_pending_time=u) > 0
1093                         && msg_pending_time <= time_now 
1094                         && (time_now - msg_pending_time) < 60 ) 
1095                 {
1096                         DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1097                                 sharename));
1098                         goto done;
1099                 }
1100                 
1101                 result = True;
1102         }
1103
1104 done:
1105         release_print_db(pdb);
1106         return result;
1107 }
1108
1109 /****************************************************************************
1110  main work for updating the lpq cahe for a printer queue
1111 ****************************************************************************/
1112
1113 static void print_queue_update_internal( const char *sharename, 
1114                                          struct printif *current_printif,
1115                                          char *lpq_command, char *lprm_command )
1116 {
1117         int i, qcount;
1118         print_queue_struct *queue = NULL;
1119         print_status_struct status;
1120         print_status_struct old_status;
1121         struct printjob *pjob;
1122         struct traverse_struct tstruct;
1123         TDB_DATA data, key;
1124         TDB_DATA jcdata;
1125         fstring keystr, cachestr;
1126         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1127
1128         if (!pdb) {
1129                 return;
1130         }
1131         
1132         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1133                 sharename, current_printif->type, lpq_command));
1134
1135         /*
1136          * Update the cache time FIRST ! Stops others even
1137          * attempting to get the lock and doing this
1138          * if the lpq takes a long time.
1139          */
1140          
1141         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1142         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1143
1144         /* get the current queue using the appropriate interface */
1145         ZERO_STRUCT(status);
1146
1147         qcount = (*(current_printif->queue_get))(sharename, 
1148                 current_printif->type, 
1149                 lpq_command, &queue, &status);
1150
1151         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", 
1152                 qcount, (qcount != 1) ? "s" : "", sharename));
1153
1154         /* Sort the queue by submission time otherwise they are displayed
1155            in hash order. */
1156
1157         qsort(queue, qcount, sizeof(print_queue_struct),
1158                 QSORT_CAST(printjob_comp));
1159
1160         /*
1161           any job in the internal database that is marked as spooled
1162           and doesn't exist in the system queue is considered finished
1163           and removed from the database
1164
1165           any job in the system database but not in the internal database 
1166           is added as a unix job
1167
1168           fill in any system job numbers as we go
1169         */
1170
1171         jcdata = get_jobs_changed_data(pdb);
1172
1173         for (i=0; i<qcount; i++) {
1174                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1175
1176                 if (jobid == (uint32)-1) {
1177                         /* assume its a unix print job */
1178                         print_unix_job(sharename, &queue[i], jobid);
1179                         continue;
1180                 }
1181
1182                 /* we have an active SMB print job - update its status */
1183                 pjob = print_job_find(sharename, jobid);
1184                 if (!pjob) {
1185                         /* err, somethings wrong. Probably smbd was restarted
1186                            with jobs in the queue. All we can do is treat them
1187                            like unix jobs. Pity. */
1188                         print_unix_job(sharename, &queue[i], jobid);
1189                         continue;
1190                 }
1191
1192                 pjob->sysjob = queue[i].job;
1193
1194                 /* don't reset the status on jobs to be deleted */
1195
1196                 if ( pjob->status != LPQ_DELETING )
1197                         pjob->status = queue[i].status;
1198
1199                 pjob_store(sharename, jobid, pjob);
1200
1201                 check_job_changed(sharename, jcdata, jobid);
1202         }
1203
1204         SAFE_FREE(jcdata.dptr);
1205
1206         /* now delete any queued entries that don't appear in the
1207            system queue */
1208         tstruct.queue = queue;
1209         tstruct.qcount = qcount;
1210         tstruct.snum = -1;
1211         tstruct.total_jobs = 0;
1212         tstruct.lpq_time = time(NULL);
1213         tstruct.sharename = sharename;
1214         tstruct.lprm_command = lprm_command;
1215         tstruct.print_if = current_printif;
1216
1217         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1218
1219         /* Store the linearised queue, max jobs only. */
1220         store_queue_struct(pdb, &tstruct);
1221
1222         SAFE_FREE(tstruct.queue);
1223
1224         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1225                                 sharename, tstruct.total_jobs ));
1226
1227         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1228
1229         get_queue_status(sharename, &old_status);
1230         if (old_status.qcount != qcount)
1231                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1232                                         old_status.qcount, qcount, sharename));
1233
1234         /* store the new queue status structure */
1235         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1236         key.dptr = keystr;
1237         key.dsize = strlen(keystr);
1238
1239         status.qcount = qcount;
1240         data.dptr = (char *)&status;
1241         data.dsize = sizeof(status);
1242         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1243
1244         /*
1245          * Update the cache time again. We want to do this call
1246          * as little as possible...
1247          */
1248
1249         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1250         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1251
1252         /* clear the msg pending record for this queue */
1253
1254         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1255
1256         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1257                 /* log a message but continue on */
1258
1259                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1260                         sharename));
1261         }
1262
1263         release_print_db( pdb );
1264
1265         return;
1266 }
1267
1268 /****************************************************************************
1269  Update the internal database from the system print queue for a queue.
1270  obtain a lock on the print queue before proceeding (needed when mutiple
1271  smbd processes maytry to update the lpq cache concurrently).
1272 ****************************************************************************/
1273
1274 static void print_queue_update_with_lock( const char *sharename, 
1275                                           struct printif *current_printif,
1276                                           char *lpq_command, char *lprm_command )
1277 {
1278         fstring keystr;
1279         struct tdb_print_db *pdb;
1280
1281         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1282         pdb = get_print_db_byname(sharename);
1283         if (!pdb)
1284                 return;
1285
1286         if ( !print_cache_expired(sharename, False) ) {
1287                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1288                 release_print_db(pdb);
1289                 return;
1290         }
1291         
1292         /*
1293          * Check to see if someone else is doing this update.
1294          * This is essentially a mutex on the update.
1295          */
1296
1297         if (get_updating_pid(sharename) != -1) {
1298                 release_print_db(pdb);
1299                 return;
1300         }
1301
1302         /* Lock the queue for the database update */
1303
1304         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1305         /* Only wait 10 seconds for this. */
1306         if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1307                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1308                 release_print_db(pdb);
1309                 return;
1310         }
1311
1312         /*
1313          * Ensure that no one else got in here.
1314          * If the updating pid is still -1 then we are
1315          * the winner.
1316          */
1317
1318         if (get_updating_pid(sharename) != -1) {
1319                 /*
1320                  * Someone else is doing the update, exit.
1321                  */
1322                 tdb_unlock_bystring(pdb->tdb, keystr);
1323                 release_print_db(pdb);
1324                 return;
1325         }
1326
1327         /*
1328          * We're going to do the update ourselves.
1329          */
1330
1331         /* Tell others we're doing the update. */
1332         set_updating_pid(sharename, True);
1333
1334         /*
1335          * Allow others to enter and notice we're doing
1336          * the update.
1337          */
1338
1339         tdb_unlock_bystring(pdb->tdb, keystr);
1340
1341         /* do the main work now */
1342         
1343         print_queue_update_internal( sharename, current_printif, 
1344                 lpq_command, lprm_command );
1345         
1346         /* Delete our pid from the db. */
1347         set_updating_pid(sharename, False);
1348         release_print_db(pdb);
1349 }
1350
1351 /****************************************************************************
1352 this is the receive function of the background lpq updater
1353 ****************************************************************************/
1354 static void print_queue_receive(int msg_type, struct process_id src,
1355                                 void *buf, size_t msglen,
1356                                 void *private_data)
1357 {
1358         fstring sharename;
1359         pstring lpqcommand, lprmcommand;
1360         int printing_type;
1361         size_t len;
1362
1363         len = tdb_unpack( (char *)buf, msglen, "fdPP",
1364                 sharename,
1365                 &printing_type,
1366                 lpqcommand,
1367                 lprmcommand );
1368
1369         if ( len == -1 ) {
1370                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1371                 return;
1372         }
1373
1374         print_queue_update_with_lock(sharename, 
1375                 get_printer_fns_from_type((enum printing_types)printing_type),
1376                 lpqcommand, lprmcommand );
1377
1378         return;
1379 }
1380
1381 static pid_t background_lpq_updater_pid = -1;
1382
1383 /****************************************************************************
1384 main thread of the background lpq updater
1385 ****************************************************************************/
1386 void start_background_queue(void)
1387 {
1388         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1389         background_lpq_updater_pid = sys_fork();
1390
1391         if (background_lpq_updater_pid == -1) {
1392                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1393                 exit(1);
1394         }
1395
1396         if(background_lpq_updater_pid == 0) {
1397                 /* Child. */
1398                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1399
1400                 claim_connection( NULL, "smbd lpq backend", 0, False, 
1401                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1402
1403                 if (!locking_init(0)) {
1404                         exit(1);
1405                 }
1406
1407                 message_register(MSG_PRINTER_UPDATE, print_queue_receive,
1408                                  NULL);
1409                 
1410                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1411                 while (1) {
1412                         pause();
1413                         
1414                         /* check for some essential signals first */
1415                         
1416                         if (got_sig_term) {
1417                                 exit_server_cleanly(NULL);
1418                         }
1419
1420                         if (reload_after_sighup) {
1421                                 change_to_root_user();
1422                                 DEBUG(1,("Reloading services after SIGHUP\n"));
1423                                 reload_services(False);
1424                                 reload_after_sighup = 0;
1425                         }
1426                         
1427                         /* now check for messages */
1428                         
1429                         DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1430                         message_dispatch();
1431
1432                         /* process any pending print change notify messages */
1433
1434                         print_notify_send_messages(0);
1435                 }
1436         }
1437 }
1438
1439 /****************************************************************************
1440 update the internal database from the system print queue for a queue
1441 ****************************************************************************/
1442
1443 static void print_queue_update(int snum, BOOL force)
1444 {
1445         fstring key;
1446         fstring sharename;
1447         pstring lpqcommand, lprmcommand;
1448         char *buffer = NULL;
1449         size_t len = 0;
1450         size_t newlen;
1451         struct tdb_print_db *pdb;
1452         int type;
1453         struct printif *current_printif;
1454
1455         fstrcpy( sharename, lp_const_servicename(snum));
1456
1457         /* don't strip out characters like '$' from the printername */
1458         
1459         pstrcpy( lpqcommand, lp_lpqcommand(snum));
1460         string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), 
1461                      False, False, False );
1462         standard_sub_advanced(lp_servicename(snum),
1463                               current_user_info.unix_name, "",
1464                               current_user.ut.gid,
1465                               get_current_username(),
1466                               current_user_info.domain,
1467                               lpqcommand, sizeof(lpqcommand) );
1468         
1469         pstrcpy( lprmcommand, lp_lprmcommand(snum));
1470         string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), 
1471                      False, False, False );
1472         standard_sub_advanced(lp_servicename(snum),
1473                               current_user_info.unix_name, "",
1474                               current_user.ut.gid,
1475                               get_current_username(),
1476                               current_user_info.domain,
1477                               lprmcommand, sizeof(lprmcommand) );
1478         
1479         /* 
1480          * Make sure that the background queue process exists.  
1481          * Otherwise just do the update ourselves 
1482          */
1483         
1484         if ( force || background_lpq_updater_pid == -1 ) {
1485                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1486                 current_printif = get_printer_fns( snum );
1487                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1488
1489                 return;
1490         }
1491
1492         type = lp_printing(snum);
1493         
1494         /* get the length */
1495
1496         len = tdb_pack( NULL, 0, "fdPP",
1497                 sharename,
1498                 type,
1499                 lpqcommand, 
1500                 lprmcommand );
1501
1502         buffer = SMB_XMALLOC_ARRAY( char, len );
1503
1504         /* now pack the buffer */
1505         newlen = tdb_pack( buffer, len, "fdPP",
1506                 sharename,
1507                 type,
1508                 lpqcommand,
1509                 lprmcommand );
1510
1511         SMB_ASSERT( newlen == len );
1512
1513         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1514                 "type = %d, lpq command = [%s] lprm command = [%s]\n", 
1515                 sharename, type, lpqcommand, lprmcommand ));
1516
1517         /* here we set a msg pending record for other smbd processes 
1518            to throttle the number of duplicate print_queue_update msgs
1519            sent.  */
1520
1521         pdb = get_print_db_byname(sharename);
1522         if (!pdb) {
1523                 SAFE_FREE(buffer);
1524                 return;
1525         }
1526
1527         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1528
1529         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1530                 /* log a message but continue on */
1531
1532                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1533                         sharename));
1534         }
1535
1536         release_print_db( pdb );
1537
1538         /* finally send the message */
1539         
1540         message_send_pid(pid_to_procid(background_lpq_updater_pid),
1541                  MSG_PRINTER_UPDATE, buffer, len, False);
1542
1543         SAFE_FREE( buffer );
1544
1545         return;
1546 }
1547
1548 /****************************************************************************
1549  Create/Update an entry in the print tdb that will allow us to send notify
1550  updates only to interested smbd's. 
1551 ****************************************************************************/
1552
1553 BOOL print_notify_register_pid(int snum)
1554 {
1555         TDB_DATA data;
1556         struct tdb_print_db *pdb = NULL;
1557         TDB_CONTEXT *tdb = NULL;
1558         const char *printername;
1559         uint32 mypid = (uint32)sys_getpid();
1560         BOOL ret = False;
1561         size_t i;
1562
1563         /* if (snum == -1), then the change notify request was
1564            on a print server handle and we need to register on
1565            all print queus */
1566            
1567         if (snum == -1) 
1568         {
1569                 int num_services = lp_numservices();
1570                 int idx;
1571                 
1572                 for ( idx=0; idx<num_services; idx++ ) {
1573                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1574                                 print_notify_register_pid(idx);
1575                 }
1576                 
1577                 return True;
1578         }
1579         else /* register for a specific printer */
1580         {
1581                 printername = lp_const_servicename(snum);
1582                 pdb = get_print_db_byname(printername);
1583                 if (!pdb)
1584                         return False;
1585                 tdb = pdb->tdb;
1586         }
1587
1588         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1589                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1590                                         printername));
1591                 if (pdb)
1592                         release_print_db(pdb);
1593                 return False;
1594         }
1595
1596         data = get_printer_notify_pid_list( tdb, printername, True );
1597
1598         /* Add ourselves and increase the refcount. */
1599
1600         for (i = 0; i < data.dsize; i += 8) {
1601                 if (IVAL(data.dptr,i) == mypid) {
1602                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1603                         SIVAL(data.dptr, i+4, new_refcount);
1604                         break;
1605                 }
1606         }
1607
1608         if (i == data.dsize) {
1609                 /* We weren't in the list. Realloc. */
1610                 data.dptr = (char *)SMB_REALLOC(data.dptr, data.dsize + 8);
1611                 if (!data.dptr) {
1612                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1613                                                 printername));
1614                         goto done;
1615                 }
1616                 data.dsize += 8;
1617                 SIVAL(data.dptr,data.dsize - 8,mypid);
1618                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1619         }
1620
1621         /* Store back the record. */
1622         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1623                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1624 list for printer %s\n", printername));
1625                 goto done;
1626         }
1627
1628         ret = True;
1629
1630  done:
1631
1632         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1633         if (pdb)
1634                 release_print_db(pdb);
1635         SAFE_FREE(data.dptr);
1636         return ret;
1637 }
1638
1639 /****************************************************************************
1640  Update an entry in the print tdb that will allow us to send notify
1641  updates only to interested smbd's. 
1642 ****************************************************************************/
1643
1644 BOOL print_notify_deregister_pid(int snum)
1645 {
1646         TDB_DATA data;
1647         struct tdb_print_db *pdb = NULL;
1648         TDB_CONTEXT *tdb = NULL;
1649         const char *printername;
1650         uint32 mypid = (uint32)sys_getpid();
1651         size_t i;
1652         BOOL ret = False;
1653
1654         /* if ( snum == -1 ), we are deregister a print server handle
1655            which means to deregister on all print queues */
1656            
1657         if (snum == -1) 
1658         {
1659                 int num_services = lp_numservices();
1660                 int idx;
1661                 
1662                 for ( idx=0; idx<num_services; idx++ ) {
1663                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1664                                 print_notify_deregister_pid(idx);
1665                 }
1666                 
1667                 return True;
1668         }
1669         else /* deregister a specific printer */
1670         {
1671                 printername = lp_const_servicename(snum);
1672                 pdb = get_print_db_byname(printername);
1673                 if (!pdb)
1674                         return False;
1675                 tdb = pdb->tdb;
1676         }
1677
1678         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1679                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1680 printer %s database\n", printername));
1681                 if (pdb)
1682                         release_print_db(pdb);
1683                 return False;
1684         }
1685
1686         data = get_printer_notify_pid_list( tdb, printername, True );
1687
1688         /* Reduce refcount. Remove ourselves if zero. */
1689
1690         for (i = 0; i < data.dsize; ) {
1691                 if (IVAL(data.dptr,i) == mypid) {
1692                         uint32 refcount = IVAL(data.dptr, i+4);
1693
1694                         refcount--;
1695
1696                         if (refcount == 0) {
1697                                 if (data.dsize - i > 8)
1698                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1699                                 data.dsize -= 8;
1700                                 continue;
1701                         }
1702                         SIVAL(data.dptr, i+4, refcount);
1703                 }
1704
1705                 i += 8;
1706         }
1707
1708         if (data.dsize == 0)
1709                 SAFE_FREE(data.dptr);
1710
1711         /* Store back the record. */
1712         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1713                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1714 list for printer %s\n", printername));
1715                 goto done;
1716         }
1717
1718         ret = True;
1719
1720   done:
1721
1722         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1723         if (pdb)
1724                 release_print_db(pdb);
1725         SAFE_FREE(data.dptr);
1726         return ret;
1727 }
1728
1729 /****************************************************************************
1730  Check if a jobid is valid. It is valid if it exists in the database.
1731 ****************************************************************************/
1732
1733 BOOL print_job_exists(const char* sharename, uint32 jobid)
1734 {
1735         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1736         BOOL ret;
1737
1738         if (!pdb)
1739                 return False;
1740         ret = tdb_exists(pdb->tdb, print_key(jobid));
1741         release_print_db(pdb);
1742         return ret;
1743 }
1744
1745 /****************************************************************************
1746  Give the fd used for a jobid.
1747 ****************************************************************************/
1748
1749 int print_job_fd(const char* sharename, uint32 jobid)
1750 {
1751         struct printjob *pjob = print_job_find(sharename, jobid);
1752         if (!pjob)
1753                 return -1;
1754         /* don't allow another process to get this info - it is meaningless */
1755         if (pjob->pid != sys_getpid())
1756                 return -1;
1757         return pjob->fd;
1758 }
1759
1760 /****************************************************************************
1761  Give the filename used for a jobid.
1762  Only valid for the process doing the spooling and when the job
1763  has not been spooled.
1764 ****************************************************************************/
1765
1766 char *print_job_fname(const char* sharename, uint32 jobid)
1767 {
1768         struct printjob *pjob = print_job_find(sharename, jobid);
1769         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1770                 return NULL;
1771         return pjob->filename;
1772 }
1773
1774
1775 /****************************************************************************
1776  Give the filename used for a jobid.
1777  Only valid for the process doing the spooling and when the job
1778  has not been spooled.
1779 ****************************************************************************/
1780
1781 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1782 {
1783         struct printjob *pjob = print_job_find(sharename, jobid);
1784         
1785         if ( !pjob )
1786                 return NULL;
1787                 
1788         return pjob->nt_devmode;
1789 }
1790
1791 /****************************************************************************
1792  Set the place in the queue for a job.
1793 ****************************************************************************/
1794
1795 BOOL print_job_set_place(const char *sharename, uint32 jobid, int place)
1796 {
1797         DEBUG(2,("print_job_set_place not implemented yet\n"));
1798         return False;
1799 }
1800
1801 /****************************************************************************
1802  Set the name of a job. Only possible for owner.
1803 ****************************************************************************/
1804
1805 BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name)
1806 {
1807         struct printjob *pjob;
1808
1809         pjob = print_job_find(sharename, jobid);
1810         if (!pjob || pjob->pid != sys_getpid())
1811                 return False;
1812
1813         fstrcpy(pjob->jobname, name);
1814         return pjob_store(sharename, jobid, pjob);
1815 }
1816
1817 /***************************************************************************
1818  Remove a jobid from the 'jobs changed' list.
1819 ***************************************************************************/
1820
1821 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1822 {
1823         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1824         TDB_DATA data, key;
1825         size_t job_count, i;
1826         BOOL ret = False;
1827         BOOL gotlock = False;
1828
1829         if (!pdb) {
1830                 return False;
1831         }
1832
1833         ZERO_STRUCT(data);
1834
1835         key = string_tdb_data("INFO/jobs_changed");
1836
1837         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1838                 goto out;
1839
1840         gotlock = True;
1841
1842         data = tdb_fetch(pdb->tdb, key);
1843
1844         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1845                 goto out;
1846
1847         job_count = data.dsize / 4;
1848         for (i = 0; i < job_count; i++) {
1849                 uint32 ch_jobid;
1850
1851                 ch_jobid = IVAL(data.dptr, i*4);
1852                 if (ch_jobid == jobid) {
1853                         if (i < job_count -1 )
1854                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1855                         data.dsize -= 4;
1856                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1857                                 goto out;
1858                         break;
1859                 }
1860         }
1861
1862         ret = True;
1863   out:
1864
1865         if (gotlock)
1866                 tdb_chainunlock(pdb->tdb, key);
1867         SAFE_FREE(data.dptr);
1868         release_print_db(pdb);
1869         if (ret)
1870                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1871         else
1872                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1873         return ret;
1874 }
1875
1876 /****************************************************************************
1877  Delete a print job - don't update queue.
1878 ****************************************************************************/
1879
1880 static BOOL print_job_delete1(int snum, uint32 jobid)
1881 {
1882         const char* sharename = lp_const_servicename(snum);
1883         struct printjob *pjob = print_job_find(sharename, jobid);
1884         int result = 0;
1885         struct printif *current_printif = get_printer_fns( snum );
1886
1887         if (!pjob)
1888                 return False;
1889
1890         /*
1891          * If already deleting just return.
1892          */
1893
1894         if (pjob->status == LPQ_DELETING)
1895                 return True;
1896
1897         /* Hrm - we need to be able to cope with deleting a job before it
1898            has reached the spooler.  Just mark it as LPQ_DELETING and 
1899            let the print_queue_update() code rmeove the record */
1900            
1901
1902         if (pjob->sysjob == -1) {
1903                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1904         }
1905
1906         /* Set the tdb entry to be deleting. */
1907
1908         pjob->status = LPQ_DELETING;
1909         pjob_store(sharename, jobid, pjob);
1910
1911         if (pjob->spooled && pjob->sysjob != -1) 
1912         {
1913                 result = (*(current_printif->job_delete))(
1914                         PRINTERNAME(snum),
1915                         lp_lprmcommand(snum), 
1916                         pjob);
1917
1918                 /* Delete the tdb entry if the delete succeeded or the job hasn't
1919                    been spooled. */
1920
1921                 if (result == 0) {
1922                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1923                         int njobs = 1;
1924
1925                         if (!pdb)
1926                                 return False;
1927                         pjob_delete(sharename, jobid);
1928                         /* Ensure we keep a rough count of the number of total jobs... */
1929                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1930                         release_print_db(pdb);
1931                 }
1932         }
1933
1934         remove_from_jobs_changed( sharename, jobid );
1935
1936         return (result == 0);
1937 }
1938
1939 /****************************************************************************
1940  Return true if the current user owns the print job.
1941 ****************************************************************************/
1942
1943 static BOOL is_owner(struct current_user *user, const char *servicename,
1944                      uint32 jobid)
1945 {
1946         struct printjob *pjob = print_job_find(servicename, jobid);
1947         user_struct *vuser;
1948
1949         if (!pjob || !user)
1950                 return False;
1951
1952         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1953                 return strequal(pjob->user, vuser->user.smb_name);
1954         } else {
1955                 return strequal(pjob->user, uidtoname(user->ut.uid));
1956         }
1957 }
1958
1959 /****************************************************************************
1960  Delete a print job.
1961 ****************************************************************************/
1962
1963 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1964 {
1965         const char* sharename = lp_const_servicename( snum );
1966         struct printjob *pjob;
1967         BOOL    owner;
1968         char    *fname;
1969
1970         *errcode = WERR_OK;
1971                 
1972         owner = is_owner(user, lp_const_servicename(snum), jobid);
1973         
1974         /* Check access against security descriptor or whether the user
1975            owns their job. */
1976
1977         if (!owner && 
1978             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1979                 DEBUG(3, ("delete denied by security descriptor\n"));
1980                 *errcode = WERR_ACCESS_DENIED;
1981
1982                 /* BEGIN_ADMIN_LOG */
1983                 sys_adminlog( LOG_ERR, 
1984                               "Permission denied-- user not allowed to delete, \
1985 pause, or resume print job. User name: %s. Printer name: %s.",
1986                               uidtoname(user->ut.uid), PRINTERNAME(snum) );
1987                 /* END_ADMIN_LOG */
1988
1989                 return False;
1990         }
1991
1992         /* 
1993          * get the spooled filename of the print job
1994          * if this works, then the file has not been spooled
1995          * to the underlying print system.  Just delete the 
1996          * spool file & return.
1997          */
1998          
1999         if ( (fname = print_job_fname( sharename, jobid )) != NULL )
2000         {
2001                 /* remove the spool file */
2002                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
2003                 if ( unlink( fname ) == -1 ) {
2004                         *errcode = map_werror_from_unix(errno);
2005                         return False;
2006                 }
2007         }
2008         
2009         if (!print_job_delete1(snum, jobid)) {
2010                 *errcode = WERR_ACCESS_DENIED;
2011                 return False;
2012         }
2013
2014         /* force update the database and say the delete failed if the
2015            job still exists */
2016
2017         print_queue_update(snum, True);
2018         
2019         pjob = print_job_find(sharename, jobid);
2020         if ( pjob && (pjob->status != LPQ_DELETING) )
2021                 *errcode = WERR_ACCESS_DENIED;
2022
2023         return (pjob == NULL );
2024 }
2025
2026 /****************************************************************************
2027  Pause a job.
2028 ****************************************************************************/
2029
2030 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2031 {
2032         const char* sharename = lp_const_servicename(snum);
2033         struct printjob *pjob;
2034         int ret = -1;
2035         struct printif *current_printif = get_printer_fns( snum );
2036
2037         pjob = print_job_find(sharename, jobid);
2038         
2039         if (!pjob || !user) {
2040                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2041                         (unsigned int)jobid ));
2042                 return False;
2043         }
2044
2045         if (!pjob->spooled || pjob->sysjob == -1) {
2046                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2047                         (int)pjob->sysjob, (unsigned int)jobid ));
2048                 return False;
2049         }
2050
2051         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2052             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2053                 DEBUG(3, ("pause denied by security descriptor\n"));
2054
2055                 /* BEGIN_ADMIN_LOG */
2056                 sys_adminlog( LOG_ERR, 
2057                         "Permission denied-- user not allowed to delete, \
2058 pause, or resume print job. User name: %s. Printer name: %s.",
2059                                 uidtoname(user->ut.uid), PRINTERNAME(snum) );
2060                 /* END_ADMIN_LOG */
2061
2062                 *errcode = WERR_ACCESS_DENIED;
2063                 return False;
2064         }
2065
2066         /* need to pause the spooled entry */
2067         ret = (*(current_printif->job_pause))(snum, pjob);
2068
2069         if (ret != 0) {
2070                 *errcode = WERR_INVALID_PARAM;
2071                 return False;
2072         }
2073
2074         /* force update the database */
2075         print_cache_flush(lp_const_servicename(snum));
2076
2077         /* Send a printer notify message */
2078
2079         notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
2080
2081         /* how do we tell if this succeeded? */
2082
2083         return True;
2084 }
2085
2086 /****************************************************************************
2087  Resume a job.
2088 ****************************************************************************/
2089
2090 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2091 {
2092         const char *sharename = lp_const_servicename(snum);
2093         struct printjob *pjob;
2094         int ret;
2095         struct printif *current_printif = get_printer_fns( snum );
2096
2097         pjob = print_job_find(sharename, jobid);
2098         
2099         if (!pjob || !user) {
2100                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2101                         (unsigned int)jobid ));
2102                 return False;
2103         }
2104
2105         if (!pjob->spooled || pjob->sysjob == -1) {
2106                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2107                         (int)pjob->sysjob, (unsigned int)jobid ));
2108                 return False;
2109         }
2110
2111         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2112             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2113                 DEBUG(3, ("resume denied by security descriptor\n"));
2114                 *errcode = WERR_ACCESS_DENIED;
2115
2116                 /* BEGIN_ADMIN_LOG */
2117                 sys_adminlog( LOG_ERR, 
2118                          "Permission denied-- user not allowed to delete, \
2119 pause, or resume print job. User name: %s. Printer name: %s.",
2120                         uidtoname(user->ut.uid), PRINTERNAME(snum) );
2121                 /* END_ADMIN_LOG */
2122                 return False;
2123         }
2124
2125         ret = (*(current_printif->job_resume))(snum, pjob);
2126
2127         if (ret != 0) {
2128                 *errcode = WERR_INVALID_PARAM;
2129                 return False;
2130         }
2131
2132         /* force update the database */
2133         print_cache_flush(lp_const_servicename(snum));
2134
2135         /* Send a printer notify message */
2136
2137         notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2138
2139         return True;
2140 }
2141
2142 /****************************************************************************
2143  Write to a print file.
2144 ****************************************************************************/
2145
2146 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2147 {
2148         const char* sharename = lp_const_servicename(snum);
2149         int return_code;
2150         struct printjob *pjob;
2151
2152         pjob = print_job_find(sharename, jobid);
2153
2154         if (!pjob)
2155                 return -1;
2156         /* don't allow another process to get this info - it is meaningless */
2157         if (pjob->pid != sys_getpid())
2158                 return -1;
2159
2160         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2161
2162         if (return_code>0) {
2163                 pjob->size += size;
2164                 pjob_store(sharename, jobid, pjob);
2165         }
2166         return return_code;
2167 }
2168
2169 /****************************************************************************
2170  Get the queue status - do not update if db is out of date.
2171 ****************************************************************************/
2172
2173 static int get_queue_status(const char* sharename, print_status_struct *status)
2174 {
2175         fstring keystr;
2176         TDB_DATA data;
2177         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2178         int len;
2179
2180         if (status) {
2181                 ZERO_STRUCTP(status);
2182         }
2183
2184         if (!pdb)
2185                 return 0;
2186
2187         if (status) {
2188                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2189                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2190                 if (data.dptr) {
2191                         if (data.dsize == sizeof(print_status_struct))
2192                                 /* this memcpy is ok since the status struct was 
2193                                    not packed before storing it in the tdb */
2194                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2195                         SAFE_FREE(data.dptr);
2196                 }
2197         }
2198         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2199         release_print_db(pdb);
2200         return (len == -1 ? 0 : len);
2201 }
2202
2203 /****************************************************************************
2204  Determine the number of jobs in a queue.
2205 ****************************************************************************/
2206
2207 int print_queue_length(int snum, print_status_struct *pstatus)
2208 {
2209         const char* sharename = lp_const_servicename( snum );
2210         print_status_struct status;
2211         int len;
2212
2213         ZERO_STRUCT( status );
2214  
2215         /* make sure the database is up to date */
2216         if (print_cache_expired(lp_const_servicename(snum), True))
2217                 print_queue_update(snum, False);
2218  
2219         /* also fetch the queue status */
2220         memset(&status, 0, sizeof(status));
2221         len = get_queue_status(sharename, &status);
2222
2223         if (pstatus)
2224                 *pstatus = status;
2225
2226         return len;
2227 }
2228
2229 /***************************************************************************
2230  Allocate a jobid. Hold the lock for as short a time as possible.
2231 ***************************************************************************/
2232
2233 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2234 {
2235         int i;
2236         uint32 jobid;
2237
2238         *pjobid = (uint32)-1;
2239
2240         for (i = 0; i < 3; i++) {
2241                 /* Lock the database - only wait 20 seconds. */
2242                 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
2243                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2244                         return False;
2245                 }
2246
2247                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2248                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2249                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2250                                         sharename));
2251                                 return False;
2252                         }
2253                         jobid = 0;
2254                 }
2255
2256                 jobid = NEXT_JOBID(jobid);
2257
2258                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2259                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2260                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2261                         return False;
2262                 }
2263
2264                 /* We've finished with the INFO/nextjob lock. */
2265                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2266                                 
2267                 if (!print_job_exists(sharename, jobid))
2268                         break;
2269         }
2270
2271         if (i > 2) {
2272                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2273                         sharename));
2274                 /* Probably full... */
2275                 errno = ENOSPC;
2276                 return False;
2277         }
2278
2279         /* Store a dummy placeholder. */
2280         {
2281                 TDB_DATA dum;
2282                 dum.dptr = NULL;
2283                 dum.dsize = 0;
2284                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2285                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2286                                 jobid ));
2287                         return False;
2288                 }
2289         }
2290
2291         *pjobid = jobid;
2292         return True;
2293 }
2294
2295 /***************************************************************************
2296  Append a jobid to the 'jobs changed' list.
2297 ***************************************************************************/
2298
2299 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2300 {
2301         TDB_DATA data;
2302         uint32 store_jobid;
2303
2304         SIVAL(&store_jobid, 0, jobid);
2305         data.dptr = (char *)&store_jobid;
2306         data.dsize = 4;
2307
2308         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2309
2310         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2311                            data) == 0);
2312 }
2313
2314 /***************************************************************************
2315  Start spooling a job - return the jobid.
2316 ***************************************************************************/
2317
2318 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2319 {
2320         uint32 jobid;
2321         char *path;
2322         struct printjob pjob;
2323         user_struct *vuser;
2324         const char *sharename = lp_const_servicename(snum);
2325         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2326         int njobs;
2327
2328         errno = 0;
2329
2330         if (!pdb)
2331                 return (uint32)-1;
2332
2333         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2334                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2335                 release_print_db(pdb);
2336                 return (uint32)-1;
2337         }
2338
2339         if (!print_time_access_check(lp_servicename(snum))) {
2340                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2341                 release_print_db(pdb);
2342                 return (uint32)-1;
2343         }
2344
2345         path = lp_pathname(snum);
2346
2347         /* see if we have sufficient disk space */
2348         if (lp_minprintspace(snum)) {
2349                 SMB_BIG_UINT dspace, dsize;
2350                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2351                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2352                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
2353                         release_print_db(pdb);
2354                         errno = ENOSPC;
2355                         return (uint32)-1;
2356                 }
2357         }
2358
2359         /* for autoloaded printers, check that the printcap entry still exists */
2360         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2361                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2362                 release_print_db(pdb);
2363                 errno = ENOENT;
2364                 return (uint32)-1;
2365         }
2366
2367         /* Insure the maximum queue size is not violated */
2368         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2369                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2370                         sharename, njobs, lp_maxprintjobs(snum) ));
2371                 release_print_db(pdb);
2372                 errno = ENOSPC;
2373                 return (uint32)-1;
2374         }
2375
2376         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2377                 sharename, njobs, lp_maxprintjobs(snum) ));
2378
2379         if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2380                 goto fail;
2381
2382         /* create the database entry */
2383         
2384         ZERO_STRUCT(pjob);
2385         
2386         pjob.pid = sys_getpid();
2387         pjob.sysjob = -1;
2388         pjob.fd = -1;
2389         pjob.starttime = time(NULL);
2390         pjob.status = LPQ_SPOOLING;
2391         pjob.size = 0;
2392         pjob.spooled = False;
2393         pjob.smbjob = True;
2394         pjob.nt_devmode = nt_devmode;
2395         
2396         fstrcpy(pjob.jobname, jobname);
2397
2398         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2399                 fstrcpy(pjob.user, lp_printjob_username(snum));
2400                 standard_sub_basic(vuser->user.smb_name, vuser->user.domain, 
2401                                    pjob.user, sizeof(pjob.user)-1);
2402                 /* ensure NULL termination */ 
2403                 pjob.user[sizeof(pjob.user)-1] = '\0'; 
2404         } else {
2405                 fstrcpy(pjob.user, uidtoname(user->ut.uid));
2406         }
2407
2408         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2409
2410         /* we have a job entry - now create the spool file */
2411         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
2412                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2413         pjob.fd = smb_mkstemp(pjob.filename);
2414
2415         if (pjob.fd == -1) {
2416                 if (errno == EACCES) {
2417                         /* Common setup error, force a report. */
2418                         DEBUG(0, ("print_job_start: insufficient permissions \
2419 to open spool file %s.\n", pjob.filename));
2420                 } else {
2421                         /* Normal case, report at level 3 and above. */
2422                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2423                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2424                 }
2425                 goto fail;
2426         }
2427
2428         pjob_store(sharename, jobid, &pjob);
2429
2430         /* Update the 'jobs changed' entry used by print_queue_status. */
2431         add_to_jobs_changed(pdb, jobid);
2432
2433         /* Ensure we keep a rough count of the number of total jobs... */
2434         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2435
2436         release_print_db(pdb);
2437
2438         return jobid;
2439
2440  fail:
2441         if (jobid != -1)
2442                 pjob_delete(sharename, jobid);
2443
2444         release_print_db(pdb);
2445
2446         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2447         return (uint32)-1;
2448 }
2449
2450 /****************************************************************************
2451  Update the number of pages spooled to jobid
2452 ****************************************************************************/
2453
2454 void print_job_endpage(int snum, uint32 jobid)
2455 {
2456         const char* sharename = lp_const_servicename(snum);
2457         struct printjob *pjob;
2458
2459         pjob = print_job_find(sharename, jobid);
2460         if (!pjob)
2461                 return;
2462         /* don't allow another process to get this info - it is meaningless */
2463         if (pjob->pid != sys_getpid())
2464                 return;
2465
2466         pjob->page_count++;
2467         pjob_store(sharename, jobid, pjob);
2468 }
2469
2470 /****************************************************************************
2471  Print a file - called on closing the file. This spools the job.
2472  If normal close is false then we're tearing down the jobs - treat as an
2473  error.
2474 ****************************************************************************/
2475
2476 BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
2477 {
2478         const char* sharename = lp_const_servicename(snum);
2479         struct printjob *pjob;
2480         int ret;
2481         SMB_STRUCT_STAT sbuf;
2482         struct printif *current_printif = get_printer_fns( snum );
2483
2484         pjob = print_job_find(sharename, jobid);
2485
2486         if (!pjob)
2487                 return False;
2488
2489         if (pjob->spooled || pjob->pid != sys_getpid())
2490                 return False;
2491
2492         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
2493                                 (sys_fstat(pjob->fd, &sbuf) == 0)) {
2494                 pjob->size = sbuf.st_size;
2495                 close(pjob->fd);
2496                 pjob->fd = -1;
2497         } else {
2498
2499                 /* 
2500                  * Not a normal close or we couldn't stat the job file,
2501                  * so something has gone wrong. Cleanup.
2502                  */
2503                 close(pjob->fd);
2504                 pjob->fd = -1;
2505                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2506                 goto fail;
2507         }
2508
2509         /* Technically, this is not quite right. If the printer has a separator
2510          * page turned on, the NT spooler prints the separator page even if the
2511          * print job is 0 bytes. 010215 JRR */
2512         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2513                 /* don't bother spooling empty files or something being deleted. */
2514                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2515                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2516                 unlink(pjob->filename);
2517                 pjob_delete(sharename, jobid);
2518                 return True;
2519         }
2520
2521         pjob->smbjob = jobid;
2522
2523         ret = (*(current_printif->job_submit))(snum, pjob);
2524
2525         if (ret)
2526                 goto fail;
2527
2528         /* The print job has been successfully handed over to the back-end */
2529         
2530         pjob->spooled = True;
2531         pjob->status = LPQ_QUEUED;
2532         pjob_store(sharename, jobid, pjob);
2533         
2534         /* make sure the database is up to date */
2535         if (print_cache_expired(lp_const_servicename(snum), True))
2536                 print_queue_update(snum, False);
2537         
2538         return True;
2539
2540 fail:
2541
2542         /* The print job was not successfully started. Cleanup */
2543         /* Still need to add proper error return propagation! 010122:JRR */
2544         unlink(pjob->filename);
2545         pjob_delete(sharename, jobid);
2546         return False;
2547 }
2548
2549 /****************************************************************************
2550  Get a snapshot of jobs in the system without traversing.
2551 ****************************************************************************/
2552
2553 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2554 {
2555         TDB_DATA data, cgdata;
2556         print_queue_struct *queue = NULL;
2557         uint32 qcount = 0;
2558         uint32 extra_count = 0;
2559         int total_count = 0;
2560         size_t len = 0;
2561         uint32 i;
2562         int max_reported_jobs = lp_max_reported_jobs(snum);
2563         BOOL ret = False;
2564         const char* sharename = lp_servicename(snum);
2565
2566         /* make sure the database is up to date */
2567         if (print_cache_expired(lp_const_servicename(snum), True))
2568                 print_queue_update(snum, False);
2569  
2570         *pcount = 0;
2571         *ppqueue = NULL;
2572
2573         ZERO_STRUCT(data);
2574         ZERO_STRUCT(cgdata);
2575
2576         /* Get the stored queue data. */
2577         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2578         
2579         if (data.dptr && data.dsize >= sizeof(qcount))
2580                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2581                 
2582         /* Get the changed jobs list. */
2583         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2584         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2585                 extra_count = cgdata.dsize/4;
2586
2587         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2588
2589         /* Allocate the queue size. */
2590         if (qcount == 0 && extra_count == 0)
2591                 goto out;
2592
2593         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2594                 goto out;
2595
2596         /* Retrieve the linearised queue data. */
2597
2598         for( i  = 0; i < qcount; i++) {
2599                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2600                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2601                                 &qjob,
2602                                 &qsize,
2603                                 &qpage_count,
2604                                 &qstatus,
2605                                 &qpriority,
2606                                 &qtime,
2607                                 queue[i].fs_user,
2608                                 queue[i].fs_file);
2609                 queue[i].job = qjob;
2610                 queue[i].size = qsize;
2611                 queue[i].page_count = qpage_count;
2612                 queue[i].status = qstatus;
2613                 queue[i].priority = qpriority;
2614                 queue[i].time = qtime;
2615         }
2616
2617         total_count = qcount;
2618
2619         /* Add in the changed jobids. */
2620         for( i  = 0; i < extra_count; i++) {
2621                 uint32 jobid;
2622                 struct printjob *pjob;
2623
2624                 jobid = IVAL(cgdata.dptr, i*4);
2625                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2626                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2627                 if (!pjob) {
2628                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2629                         remove_from_jobs_changed(sharename, jobid);
2630                         continue;
2631                 }
2632
2633                 queue[total_count].job = jobid;
2634                 queue[total_count].size = pjob->size;
2635                 queue[total_count].page_count = pjob->page_count;
2636                 queue[total_count].status = pjob->status;
2637                 queue[total_count].priority = 1;
2638                 queue[total_count].time = pjob->starttime;
2639                 fstrcpy(queue[total_count].fs_user, pjob->user);
2640                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2641                 total_count++;
2642         }
2643
2644         /* Sort the queue by submission time otherwise they are displayed
2645            in hash order. */
2646
2647         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2648
2649         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2650
2651         if (max_reported_jobs && total_count > max_reported_jobs)
2652                 total_count = max_reported_jobs;
2653
2654         *ppqueue = queue;
2655         *pcount = total_count;
2656
2657         ret = True;
2658
2659   out:
2660
2661         SAFE_FREE(data.dptr);
2662         SAFE_FREE(cgdata.dptr);
2663         return ret;
2664 }
2665
2666 /****************************************************************************
2667  Get a printer queue listing.
2668  set queue = NULL and status = NULL if you just want to update the cache
2669 ****************************************************************************/
2670
2671 int print_queue_status(int snum, 
2672                        print_queue_struct **ppqueue,
2673                        print_status_struct *status)
2674 {
2675         fstring keystr;
2676         TDB_DATA data, key;
2677         const char *sharename;
2678         struct tdb_print_db *pdb;
2679         int count = 0;
2680
2681         /* make sure the database is up to date */
2682
2683         if (print_cache_expired(lp_const_servicename(snum), True))
2684                 print_queue_update(snum, False);
2685
2686         /* return if we are done */
2687         if ( !ppqueue || !status )
2688                 return 0;
2689
2690         *ppqueue = NULL;
2691         sharename = lp_const_servicename(snum);
2692         pdb = get_print_db_byname(sharename);
2693
2694         if (!pdb)
2695                 return 0;
2696
2697         /*
2698          * Fetch the queue status.  We must do this first, as there may
2699          * be no jobs in the queue.
2700          */
2701
2702         ZERO_STRUCTP(status);
2703         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2704         key.dptr = keystr;
2705         key.dsize = strlen(keystr);
2706         data = tdb_fetch(pdb->tdb, key);
2707         if (data.dptr) {
2708                 if (data.dsize == sizeof(*status)) {
2709                         /* this memcpy is ok since the status struct was 
2710                            not packed before storing it in the tdb */
2711                         memcpy(status, data.dptr, sizeof(*status));
2712                 }
2713                 SAFE_FREE(data.dptr);
2714         }
2715
2716         /*
2717          * Now, fetch the print queue information.  We first count the number
2718          * of entries, and then only retrieve the queue if necessary.
2719          */
2720
2721         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2722                 release_print_db(pdb);
2723                 return 0;
2724         }
2725
2726         release_print_db(pdb);
2727         return count;
2728 }
2729
2730 /****************************************************************************
2731  Pause a queue.
2732 ****************************************************************************/
2733
2734 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2735 {
2736         int ret;
2737         struct printif *current_printif = get_printer_fns( snum );
2738         
2739         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2740                 *errcode = WERR_ACCESS_DENIED;
2741                 return False;
2742         }
2743         
2744
2745         become_root();
2746                 
2747         ret = (*(current_printif->queue_pause))(snum);
2748
2749         unbecome_root();
2750                 
2751         if (ret != 0) {
2752                 *errcode = WERR_INVALID_PARAM;
2753                 return False;
2754         }
2755
2756         /* force update the database */
2757         print_cache_flush(lp_const_servicename(snum));
2758
2759         /* Send a printer notify message */
2760
2761         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2762
2763         return True;
2764 }
2765
2766 /****************************************************************************
2767  Resume a queue.
2768 ****************************************************************************/
2769
2770 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2771 {
2772         int ret;
2773         struct printif *current_printif = get_printer_fns( snum );
2774
2775         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2776                 *errcode = WERR_ACCESS_DENIED;
2777                 return False;
2778         }
2779         
2780         become_root();
2781                 
2782         ret = (*(current_printif->queue_resume))(snum);
2783
2784         unbecome_root();
2785                 
2786         if (ret != 0) {
2787                 *errcode = WERR_INVALID_PARAM;
2788                 return False;
2789         }
2790
2791         /* make sure the database is up to date */
2792         if (print_cache_expired(lp_const_servicename(snum), True))
2793                 print_queue_update(snum, True);
2794
2795         /* Send a printer notify message */
2796
2797         notify_printer_status(snum, PRINTER_STATUS_OK);
2798
2799         return True;
2800 }
2801
2802 /****************************************************************************
2803  Purge a queue - implemented by deleting all jobs that we can delete.
2804 ****************************************************************************/
2805
2806 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2807 {
2808         print_queue_struct *queue;
2809         print_status_struct status;
2810         int njobs, i;
2811         BOOL can_job_admin;
2812
2813         /* Force and update so the count is accurate (i.e. not a cached count) */
2814         print_queue_update(snum, True);
2815         
2816         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2817         njobs = print_queue_status(snum, &queue, &status);
2818         
2819         if ( can_job_admin )
2820                 become_root();
2821
2822         for (i=0;i<njobs;i++) {
2823                 BOOL owner = is_owner(user, lp_const_servicename(snum), queue[i].job);
2824
2825                 if (owner || can_job_admin) {
2826                         print_job_delete1(snum, queue[i].job);
2827                 }
2828         }
2829         
2830         if ( can_job_admin )
2831                 unbecome_root();
2832
2833         /* update the cache */
2834         print_queue_update( snum, True );
2835
2836         SAFE_FREE(queue);
2837
2838         return True;
2839 }