r22895: Convert some more calls from message_send_buf to messaging_send_buf
[ira/wip.git] / source3 / 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 = (uint8 *)&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 = 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 = 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 = (uint8 *)&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 = 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 = (uint8 *)&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( uint8 *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         uint8                   *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 = (uint8 *)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 = string_tdb_data(keystr);
871
872         data = tdb_fetch(pdb->tdb, key);
873         release_print_db(pdb);
874         if (!data.dptr || data.dsize != sizeof(pid_t)) {
875                 SAFE_FREE(data.dptr);
876                 return (pid_t)-1;
877         }
878
879         updating_pid = IVAL(data.dptr, 0);
880         SAFE_FREE(data.dptr);
881
882         if (process_exists_by_pid(updating_pid))
883                 return updating_pid;
884
885         return (pid_t)-1;
886 }
887
888 /****************************************************************************
889  Set the fact that we're doing the update, or have finished doing the update
890  in the tdb.
891 ****************************************************************************/
892
893 static void set_updating_pid(const fstring sharename, BOOL updating)
894 {
895         fstring keystr;
896         TDB_DATA key;
897         TDB_DATA data;
898         pid_t updating_pid = sys_getpid();
899         uint8 buffer[4];
900         
901         struct tdb_print_db *pdb = get_print_db_byname(sharename);
902
903         if (!pdb)
904                 return;
905
906         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
907         key = string_tdb_data(keystr);
908         
909         DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", 
910                 updating ? "" : "not ",
911                 sharename ));
912
913         if ( !updating ) {
914                 tdb_delete(pdb->tdb, key);
915                 release_print_db(pdb);
916                 return;
917         }
918         
919         SIVAL( buffer, 0, updating_pid);
920         data.dptr = buffer;
921         data.dsize = 4;         /* we always assume this is a 4 byte value */
922
923         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
924         release_print_db(pdb);
925 }
926
927 /****************************************************************************
928  Sort print jobs by submittal time.
929 ****************************************************************************/
930
931 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
932 {
933         /* Silly cases */
934
935         if (!j1 && !j2)
936                 return 0;
937         if (!j1)
938                 return -1;
939         if (!j2)
940                 return 1;
941
942         /* Sort on job start time */
943
944         if (j1->time == j2->time)
945                 return 0;
946         return (j1->time > j2->time) ? 1 : -1;
947 }
948
949 /****************************************************************************
950  Store the sorted queue representation for later portmon retrieval.
951  Skip deleted jobs
952 ****************************************************************************/
953
954 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
955 {
956         TDB_DATA data;
957         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
958         print_queue_struct *queue = pts->queue;
959         size_t len;
960         size_t i;
961         uint qcount;
962
963         if (max_reported_jobs && (max_reported_jobs < pts->qcount))
964                 pts->qcount = max_reported_jobs;
965         qcount = 0;
966
967         /* Work out the size. */
968         data.dsize = 0;
969         data.dsize += tdb_pack(NULL, 0, "d", qcount);
970
971         for (i = 0; i < pts->qcount; i++) {
972                 if ( queue[i].status == LPQ_DELETED )
973                         continue;
974
975                 qcount++;
976                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
977                                 (uint32)queue[i].job,
978                                 (uint32)queue[i].size,
979                                 (uint32)queue[i].page_count,
980                                 (uint32)queue[i].status,
981                                 (uint32)queue[i].priority,
982                                 (uint32)queue[i].time,
983                                 queue[i].fs_user,
984                                 queue[i].fs_file);
985         }
986
987         if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
988                 return;
989
990         len = 0;
991         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
992         for (i = 0; i < pts->qcount; i++) {
993                 if ( queue[i].status == LPQ_DELETED )
994                         continue;
995
996                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
997                                 (uint32)queue[i].job,
998                                 (uint32)queue[i].size,
999                                 (uint32)queue[i].page_count,
1000                                 (uint32)queue[i].status,
1001                                 (uint32)queue[i].priority,
1002                                 (uint32)queue[i].time,
1003                                 queue[i].fs_user,
1004                                 queue[i].fs_file);
1005         }
1006
1007         tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1008                   TDB_REPLACE);
1009         SAFE_FREE(data.dptr);
1010         return;
1011 }
1012
1013 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1014 {
1015         TDB_DATA data;
1016
1017         ZERO_STRUCT(data);
1018
1019         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1020         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1021                 SAFE_FREE(data.dptr);
1022                 ZERO_STRUCT(data);
1023         }
1024
1025         return data;
1026 }
1027
1028 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1029 {
1030         unsigned int i;
1031         unsigned int job_count = data.dsize / 4;
1032
1033         for (i = 0; i < job_count; i++) {
1034                 uint32 ch_jobid;
1035
1036                 ch_jobid = IVAL(data.dptr, i*4);
1037                 if (ch_jobid == jobid)
1038                         remove_from_jobs_changed(sharename, jobid);
1039         }
1040 }
1041
1042 /****************************************************************************
1043  Check if the print queue has been updated recently enough.
1044 ****************************************************************************/
1045
1046 static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
1047 {
1048         fstring key;
1049         time_t last_qscan_time, time_now = time(NULL);
1050         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1051         BOOL result = False;
1052
1053         if (!pdb)
1054                 return False;
1055
1056         snprintf(key, sizeof(key), "CACHE/%s", sharename);
1057         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1058
1059         /*
1060          * Invalidate the queue for 3 reasons.
1061          * (1). last queue scan time == -1.
1062          * (2). Current time - last queue scan time > allowed cache time.
1063          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1064          * This last test picks up machines for which the clock has been moved
1065          * forward, an lpq scan done and then the clock moved back. Otherwise
1066          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1067          */
1068
1069         if (last_qscan_time == ((time_t)-1) 
1070                 || (time_now - last_qscan_time) >= lp_lpqcachetime() 
1071                 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) 
1072         {
1073                 uint32 u;
1074                 time_t msg_pending_time;
1075
1076                 DEBUG(4, ("print_cache_expired: cache expired for queue %s " 
1077                         "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", 
1078                         sharename, (int)last_qscan_time, (int)time_now, 
1079                         (int)lp_lpqcachetime() ));
1080
1081                 /* check if another smbd has already sent a message to update the 
1082                    queue.  Give the pending message one minute to clear and 
1083                    then send another message anyways.  Make sure to check for 
1084                    clocks that have been run forward and then back again. */
1085
1086                 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1087
1088                 if ( check_pending 
1089                         && tdb_fetch_uint32( pdb->tdb, key, &u ) 
1090                         && (msg_pending_time=u) > 0
1091                         && msg_pending_time <= time_now 
1092                         && (time_now - msg_pending_time) < 60 ) 
1093                 {
1094                         DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1095                                 sharename));
1096                         goto done;
1097                 }
1098                 
1099                 result = True;
1100         }
1101
1102 done:
1103         release_print_db(pdb);
1104         return result;
1105 }
1106
1107 /****************************************************************************
1108  main work for updating the lpq cahe for a printer queue
1109 ****************************************************************************/
1110
1111 static void print_queue_update_internal( const char *sharename, 
1112                                          struct printif *current_printif,
1113                                          char *lpq_command, char *lprm_command )
1114 {
1115         int i, qcount;
1116         print_queue_struct *queue = NULL;
1117         print_status_struct status;
1118         print_status_struct old_status;
1119         struct printjob *pjob;
1120         struct traverse_struct tstruct;
1121         TDB_DATA data, key;
1122         TDB_DATA jcdata;
1123         fstring keystr, cachestr;
1124         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1125
1126         if (!pdb) {
1127                 return;
1128         }
1129         
1130         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1131                 sharename, current_printif->type, lpq_command));
1132
1133         /*
1134          * Update the cache time FIRST ! Stops others even
1135          * attempting to get the lock and doing this
1136          * if the lpq takes a long time.
1137          */
1138          
1139         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1140         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1141
1142         /* get the current queue using the appropriate interface */
1143         ZERO_STRUCT(status);
1144
1145         qcount = (*(current_printif->queue_get))(sharename, 
1146                 current_printif->type, 
1147                 lpq_command, &queue, &status);
1148
1149         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", 
1150                 qcount, (qcount != 1) ? "s" : "", sharename));
1151
1152         /* Sort the queue by submission time otherwise they are displayed
1153            in hash order. */
1154
1155         qsort(queue, qcount, sizeof(print_queue_struct),
1156                 QSORT_CAST(printjob_comp));
1157
1158         /*
1159           any job in the internal database that is marked as spooled
1160           and doesn't exist in the system queue is considered finished
1161           and removed from the database
1162
1163           any job in the system database but not in the internal database 
1164           is added as a unix job
1165
1166           fill in any system job numbers as we go
1167         */
1168
1169         jcdata = get_jobs_changed_data(pdb);
1170
1171         for (i=0; i<qcount; i++) {
1172                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1173
1174                 if (jobid == (uint32)-1) {
1175                         /* assume its a unix print job */
1176                         print_unix_job(sharename, &queue[i], jobid);
1177                         continue;
1178                 }
1179
1180                 /* we have an active SMB print job - update its status */
1181                 pjob = print_job_find(sharename, jobid);
1182                 if (!pjob) {
1183                         /* err, somethings wrong. Probably smbd was restarted
1184                            with jobs in the queue. All we can do is treat them
1185                            like unix jobs. Pity. */
1186                         print_unix_job(sharename, &queue[i], jobid);
1187                         continue;
1188                 }
1189
1190                 pjob->sysjob = queue[i].job;
1191
1192                 /* don't reset the status on jobs to be deleted */
1193
1194                 if ( pjob->status != LPQ_DELETING )
1195                         pjob->status = queue[i].status;
1196
1197                 pjob_store(sharename, jobid, pjob);
1198
1199                 check_job_changed(sharename, jcdata, jobid);
1200         }
1201
1202         SAFE_FREE(jcdata.dptr);
1203
1204         /* now delete any queued entries that don't appear in the
1205            system queue */
1206         tstruct.queue = queue;
1207         tstruct.qcount = qcount;
1208         tstruct.snum = -1;
1209         tstruct.total_jobs = 0;
1210         tstruct.lpq_time = time(NULL);
1211         tstruct.sharename = sharename;
1212         tstruct.lprm_command = lprm_command;
1213         tstruct.print_if = current_printif;
1214
1215         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1216
1217         /* Store the linearised queue, max jobs only. */
1218         store_queue_struct(pdb, &tstruct);
1219
1220         SAFE_FREE(tstruct.queue);
1221
1222         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1223                                 sharename, tstruct.total_jobs ));
1224
1225         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1226
1227         get_queue_status(sharename, &old_status);
1228         if (old_status.qcount != qcount)
1229                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1230                                         old_status.qcount, qcount, sharename));
1231
1232         /* store the new queue status structure */
1233         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1234         key = string_tdb_data(keystr);
1235
1236         status.qcount = qcount;
1237         data.dptr = (uint8 *)&status;
1238         data.dsize = sizeof(status);
1239         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1240
1241         /*
1242          * Update the cache time again. We want to do this call
1243          * as little as possible...
1244          */
1245
1246         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1247         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1248
1249         /* clear the msg pending record for this queue */
1250
1251         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1252
1253         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1254                 /* log a message but continue on */
1255
1256                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1257                         sharename));
1258         }
1259
1260         release_print_db( pdb );
1261
1262         return;
1263 }
1264
1265 /****************************************************************************
1266  Update the internal database from the system print queue for a queue.
1267  obtain a lock on the print queue before proceeding (needed when mutiple
1268  smbd processes maytry to update the lpq cache concurrently).
1269 ****************************************************************************/
1270
1271 static void print_queue_update_with_lock( const char *sharename, 
1272                                           struct printif *current_printif,
1273                                           char *lpq_command, char *lprm_command )
1274 {
1275         fstring keystr;
1276         struct tdb_print_db *pdb;
1277
1278         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1279         pdb = get_print_db_byname(sharename);
1280         if (!pdb)
1281                 return;
1282
1283         if ( !print_cache_expired(sharename, False) ) {
1284                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1285                 release_print_db(pdb);
1286                 return;
1287         }
1288         
1289         /*
1290          * Check to see if someone else is doing this update.
1291          * This is essentially a mutex on the update.
1292          */
1293
1294         if (get_updating_pid(sharename) != -1) {
1295                 release_print_db(pdb);
1296                 return;
1297         }
1298
1299         /* Lock the queue for the database update */
1300
1301         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1302         /* Only wait 10 seconds for this. */
1303         if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1304                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1305                 release_print_db(pdb);
1306                 return;
1307         }
1308
1309         /*
1310          * Ensure that no one else got in here.
1311          * If the updating pid is still -1 then we are
1312          * the winner.
1313          */
1314
1315         if (get_updating_pid(sharename) != -1) {
1316                 /*
1317                  * Someone else is doing the update, exit.
1318                  */
1319                 tdb_unlock_bystring(pdb->tdb, keystr);
1320                 release_print_db(pdb);
1321                 return;
1322         }
1323
1324         /*
1325          * We're going to do the update ourselves.
1326          */
1327
1328         /* Tell others we're doing the update. */
1329         set_updating_pid(sharename, True);
1330
1331         /*
1332          * Allow others to enter and notice we're doing
1333          * the update.
1334          */
1335
1336         tdb_unlock_bystring(pdb->tdb, keystr);
1337
1338         /* do the main work now */
1339         
1340         print_queue_update_internal( sharename, current_printif, 
1341                 lpq_command, lprm_command );
1342         
1343         /* Delete our pid from the db. */
1344         set_updating_pid(sharename, False);
1345         release_print_db(pdb);
1346 }
1347
1348 /****************************************************************************
1349 this is the receive function of the background lpq updater
1350 ****************************************************************************/
1351 static void print_queue_receive(int msg_type, struct server_id src,
1352                                 void *buf, size_t msglen,
1353                                 void *private_data)
1354 {
1355         fstring sharename;
1356         pstring lpqcommand, lprmcommand;
1357         int printing_type;
1358         size_t len;
1359
1360         len = tdb_unpack( (uint8 *)buf, msglen, "fdPP",
1361                 sharename,
1362                 &printing_type,
1363                 lpqcommand,
1364                 lprmcommand );
1365
1366         if ( len == -1 ) {
1367                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1368                 return;
1369         }
1370
1371         print_queue_update_with_lock(sharename, 
1372                 get_printer_fns_from_type((enum printing_types)printing_type),
1373                 lpqcommand, lprmcommand );
1374
1375         return;
1376 }
1377
1378 static pid_t background_lpq_updater_pid = -1;
1379
1380 /****************************************************************************
1381 main thread of the background lpq updater
1382 ****************************************************************************/
1383 void start_background_queue(void)
1384 {
1385         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1386         background_lpq_updater_pid = sys_fork();
1387
1388         if (background_lpq_updater_pid == -1) {
1389                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1390                 exit(1);
1391         }
1392
1393         if(background_lpq_updater_pid == 0) {
1394                 /* Child. */
1395                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1396
1397                 claim_connection( NULL, "smbd lpq backend", 0, False, 
1398                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1399
1400                 if (!locking_init(0)) {
1401                         exit(1);
1402                 }
1403
1404                 message_register(MSG_PRINTER_UPDATE, print_queue_receive,
1405                                  NULL);
1406                 
1407                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1408                 while (1) {
1409                         pause();
1410                         
1411                         /* check for some essential signals first */
1412                         
1413                         if (got_sig_term) {
1414                                 exit_server_cleanly(NULL);
1415                         }
1416
1417                         if (reload_after_sighup) {
1418                                 change_to_root_user();
1419                                 DEBUG(1,("Reloading services after SIGHUP\n"));
1420                                 reload_services(False);
1421                                 reload_after_sighup = 0;
1422                         }
1423                         
1424                         /* now check for messages */
1425                         
1426                         DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1427                         message_dispatch();
1428
1429                         /* process any pending print change notify messages */
1430
1431                         print_notify_send_messages(smbd_messaging_context(),
1432                                                    0);
1433                 }
1434         }
1435 }
1436
1437 /****************************************************************************
1438 update the internal database from the system print queue for a queue
1439 ****************************************************************************/
1440
1441 static void print_queue_update(int snum, BOOL force)
1442 {
1443         fstring key;
1444         fstring sharename;
1445         pstring lpqcommand, lprmcommand;
1446         uint8 *buffer = NULL;
1447         size_t len = 0;
1448         size_t newlen;
1449         struct tdb_print_db *pdb;
1450         int type;
1451         struct printif *current_printif;
1452
1453         fstrcpy( sharename, lp_const_servicename(snum));
1454
1455         /* don't strip out characters like '$' from the printername */
1456         
1457         pstrcpy( lpqcommand, lp_lpqcommand(snum));
1458         string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), 
1459                      False, False, False );
1460         standard_sub_advanced(lp_servicename(snum),
1461                               current_user_info.unix_name, "",
1462                               current_user.ut.gid,
1463                               get_current_username(),
1464                               current_user_info.domain,
1465                               lpqcommand, sizeof(lpqcommand) );
1466         
1467         pstrcpy( lprmcommand, lp_lprmcommand(snum));
1468         string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), 
1469                      False, False, False );
1470         standard_sub_advanced(lp_servicename(snum),
1471                               current_user_info.unix_name, "",
1472                               current_user.ut.gid,
1473                               get_current_username(),
1474                               current_user_info.domain,
1475                               lprmcommand, sizeof(lprmcommand) );
1476         
1477         /* 
1478          * Make sure that the background queue process exists.  
1479          * Otherwise just do the update ourselves 
1480          */
1481         
1482         if ( force || background_lpq_updater_pid == -1 ) {
1483                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1484                 current_printif = get_printer_fns( snum );
1485                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1486
1487                 return;
1488         }
1489
1490         type = lp_printing(snum);
1491         
1492         /* get the length */
1493
1494         len = tdb_pack( NULL, 0, "fdPP",
1495                 sharename,
1496                 type,
1497                 lpqcommand, 
1498                 lprmcommand );
1499
1500         buffer = SMB_XMALLOC_ARRAY( uint8, len );
1501
1502         /* now pack the buffer */
1503         newlen = tdb_pack( buffer, len, "fdPP",
1504                 sharename,
1505                 type,
1506                 lpqcommand,
1507                 lprmcommand );
1508
1509         SMB_ASSERT( newlen == len );
1510
1511         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1512                 "type = %d, lpq command = [%s] lprm command = [%s]\n", 
1513                 sharename, type, lpqcommand, lprmcommand ));
1514
1515         /* here we set a msg pending record for other smbd processes 
1516            to throttle the number of duplicate print_queue_update msgs
1517            sent.  */
1518
1519         pdb = get_print_db_byname(sharename);
1520         if (!pdb) {
1521                 SAFE_FREE(buffer);
1522                 return;
1523         }
1524
1525         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1526
1527         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1528                 /* log a message but continue on */
1529
1530                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1531                         sharename));
1532         }
1533
1534         release_print_db( pdb );
1535
1536         /* finally send the message */
1537         
1538         messaging_send_buf(smbd_messaging_context(),
1539                            pid_to_procid(background_lpq_updater_pid),
1540                            MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1541
1542         SAFE_FREE( buffer );
1543
1544         return;
1545 }
1546
1547 /****************************************************************************
1548  Create/Update an entry in the print tdb that will allow us to send notify
1549  updates only to interested smbd's. 
1550 ****************************************************************************/
1551
1552 BOOL print_notify_register_pid(int snum)
1553 {
1554         TDB_DATA data;
1555         struct tdb_print_db *pdb = NULL;
1556         TDB_CONTEXT *tdb = NULL;
1557         const char *printername;
1558         uint32 mypid = (uint32)sys_getpid();
1559         BOOL ret = False;
1560         size_t i;
1561
1562         /* if (snum == -1), then the change notify request was
1563            on a print server handle and we need to register on
1564            all print queus */
1565            
1566         if (snum == -1) 
1567         {
1568                 int num_services = lp_numservices();
1569                 int idx;
1570                 
1571                 for ( idx=0; idx<num_services; idx++ ) {
1572                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1573                                 print_notify_register_pid(idx);
1574                 }
1575                 
1576                 return True;
1577         }
1578         else /* register for a specific printer */
1579         {
1580                 printername = lp_const_servicename(snum);
1581                 pdb = get_print_db_byname(printername);
1582                 if (!pdb)
1583                         return False;
1584                 tdb = pdb->tdb;
1585         }
1586
1587         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1588                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1589                                         printername));
1590                 if (pdb)
1591                         release_print_db(pdb);
1592                 return False;
1593         }
1594
1595         data = get_printer_notify_pid_list( tdb, printername, True );
1596
1597         /* Add ourselves and increase the refcount. */
1598
1599         for (i = 0; i < data.dsize; i += 8) {
1600                 if (IVAL(data.dptr,i) == mypid) {
1601                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1602                         SIVAL(data.dptr, i+4, new_refcount);
1603                         break;
1604                 }
1605         }
1606
1607         if (i == data.dsize) {
1608                 /* We weren't in the list. Realloc. */
1609                 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1610                 if (!data.dptr) {
1611                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1612                                                 printername));
1613                         goto done;
1614                 }
1615                 data.dsize += 8;
1616                 SIVAL(data.dptr,data.dsize - 8,mypid);
1617                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1618         }
1619
1620         /* Store back the record. */
1621         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1622                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1623 list for printer %s\n", printername));
1624                 goto done;
1625         }
1626
1627         ret = True;
1628
1629  done:
1630
1631         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1632         if (pdb)
1633                 release_print_db(pdb);
1634         SAFE_FREE(data.dptr);
1635         return ret;
1636 }
1637
1638 /****************************************************************************
1639  Update an entry in the print tdb that will allow us to send notify
1640  updates only to interested smbd's. 
1641 ****************************************************************************/
1642
1643 BOOL print_notify_deregister_pid(int snum)
1644 {
1645         TDB_DATA data;
1646         struct tdb_print_db *pdb = NULL;
1647         TDB_CONTEXT *tdb = NULL;
1648         const char *printername;
1649         uint32 mypid = (uint32)sys_getpid();
1650         size_t i;
1651         BOOL ret = False;
1652
1653         /* if ( snum == -1 ), we are deregister a print server handle
1654            which means to deregister on all print queues */
1655            
1656         if (snum == -1) 
1657         {
1658                 int num_services = lp_numservices();
1659                 int idx;
1660                 
1661                 for ( idx=0; idx<num_services; idx++ ) {
1662                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1663                                 print_notify_deregister_pid(idx);
1664                 }
1665                 
1666                 return True;
1667         }
1668         else /* deregister a specific printer */
1669         {
1670                 printername = lp_const_servicename(snum);
1671                 pdb = get_print_db_byname(printername);
1672                 if (!pdb)
1673                         return False;
1674                 tdb = pdb->tdb;
1675         }
1676
1677         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1678                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1679 printer %s database\n", printername));
1680                 if (pdb)
1681                         release_print_db(pdb);
1682                 return False;
1683         }
1684
1685         data = get_printer_notify_pid_list( tdb, printername, True );
1686
1687         /* Reduce refcount. Remove ourselves if zero. */
1688
1689         for (i = 0; i < data.dsize; ) {
1690                 if (IVAL(data.dptr,i) == mypid) {
1691                         uint32 refcount = IVAL(data.dptr, i+4);
1692
1693                         refcount--;
1694
1695                         if (refcount == 0) {
1696                                 if (data.dsize - i > 8)
1697                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1698                                 data.dsize -= 8;
1699                                 continue;
1700                         }
1701                         SIVAL(data.dptr, i+4, refcount);
1702                 }
1703
1704                 i += 8;
1705         }
1706
1707         if (data.dsize == 0)
1708                 SAFE_FREE(data.dptr);
1709
1710         /* Store back the record. */
1711         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1712                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1713 list for printer %s\n", printername));
1714                 goto done;
1715         }
1716
1717         ret = True;
1718
1719   done:
1720
1721         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1722         if (pdb)
1723                 release_print_db(pdb);
1724         SAFE_FREE(data.dptr);
1725         return ret;
1726 }
1727
1728 /****************************************************************************
1729  Check if a jobid is valid. It is valid if it exists in the database.
1730 ****************************************************************************/
1731
1732 BOOL print_job_exists(const char* sharename, uint32 jobid)
1733 {
1734         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1735         BOOL ret;
1736
1737         if (!pdb)
1738                 return False;
1739         ret = tdb_exists(pdb->tdb, print_key(jobid));
1740         release_print_db(pdb);
1741         return ret;
1742 }
1743
1744 /****************************************************************************
1745  Give the fd used for a jobid.
1746 ****************************************************************************/
1747
1748 int print_job_fd(const char* sharename, uint32 jobid)
1749 {
1750         struct printjob *pjob = print_job_find(sharename, jobid);
1751         if (!pjob)
1752                 return -1;
1753         /* don't allow another process to get this info - it is meaningless */
1754         if (pjob->pid != sys_getpid())
1755                 return -1;
1756         return pjob->fd;
1757 }
1758
1759 /****************************************************************************
1760  Give the filename used for a jobid.
1761  Only valid for the process doing the spooling and when the job
1762  has not been spooled.
1763 ****************************************************************************/
1764
1765 char *print_job_fname(const char* sharename, uint32 jobid)
1766 {
1767         struct printjob *pjob = print_job_find(sharename, jobid);
1768         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1769                 return NULL;
1770         return pjob->filename;
1771 }
1772
1773
1774 /****************************************************************************
1775  Give the filename used for a jobid.
1776  Only valid for the process doing the spooling and when the job
1777  has not been spooled.
1778 ****************************************************************************/
1779
1780 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1781 {
1782         struct printjob *pjob = print_job_find(sharename, jobid);
1783         
1784         if ( !pjob )
1785                 return NULL;
1786                 
1787         return pjob->nt_devmode;
1788 }
1789
1790 /****************************************************************************
1791  Set the place in the queue for a job.
1792 ****************************************************************************/
1793
1794 BOOL print_job_set_place(const char *sharename, uint32 jobid, int place)
1795 {
1796         DEBUG(2,("print_job_set_place not implemented yet\n"));
1797         return False;
1798 }
1799
1800 /****************************************************************************
1801  Set the name of a job. Only possible for owner.
1802 ****************************************************************************/
1803
1804 BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name)
1805 {
1806         struct printjob *pjob;
1807
1808         pjob = print_job_find(sharename, jobid);
1809         if (!pjob || pjob->pid != sys_getpid())
1810                 return False;
1811
1812         fstrcpy(pjob->jobname, name);
1813         return pjob_store(sharename, jobid, pjob);
1814 }
1815
1816 /***************************************************************************
1817  Remove a jobid from the 'jobs changed' list.
1818 ***************************************************************************/
1819
1820 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1821 {
1822         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1823         TDB_DATA data, key;
1824         size_t job_count, i;
1825         BOOL ret = False;
1826         BOOL gotlock = False;
1827
1828         if (!pdb) {
1829                 return False;
1830         }
1831
1832         ZERO_STRUCT(data);
1833
1834         key = string_tdb_data("INFO/jobs_changed");
1835
1836         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1837                 goto out;
1838
1839         gotlock = True;
1840
1841         data = tdb_fetch(pdb->tdb, key);
1842
1843         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1844                 goto out;
1845
1846         job_count = data.dsize / 4;
1847         for (i = 0; i < job_count; i++) {
1848                 uint32 ch_jobid;
1849
1850                 ch_jobid = IVAL(data.dptr, i*4);
1851                 if (ch_jobid == jobid) {
1852                         if (i < job_count -1 )
1853                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1854                         data.dsize -= 4;
1855                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1856                                 goto out;
1857                         break;
1858                 }
1859         }
1860
1861         ret = True;
1862   out:
1863
1864         if (gotlock)
1865                 tdb_chainunlock(pdb->tdb, key);
1866         SAFE_FREE(data.dptr);
1867         release_print_db(pdb);
1868         if (ret)
1869                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1870         else
1871                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1872         return ret;
1873 }
1874
1875 /****************************************************************************
1876  Delete a print job - don't update queue.
1877 ****************************************************************************/
1878
1879 static BOOL print_job_delete1(int snum, uint32 jobid)
1880 {
1881         const char* sharename = lp_const_servicename(snum);
1882         struct printjob *pjob = print_job_find(sharename, jobid);
1883         int result = 0;
1884         struct printif *current_printif = get_printer_fns( snum );
1885
1886         if (!pjob)
1887                 return False;
1888
1889         /*
1890          * If already deleting just return.
1891          */
1892
1893         if (pjob->status == LPQ_DELETING)
1894                 return True;
1895
1896         /* Hrm - we need to be able to cope with deleting a job before it
1897            has reached the spooler.  Just mark it as LPQ_DELETING and 
1898            let the print_queue_update() code rmeove the record */
1899            
1900
1901         if (pjob->sysjob == -1) {
1902                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1903         }
1904
1905         /* Set the tdb entry to be deleting. */
1906
1907         pjob->status = LPQ_DELETING;
1908         pjob_store(sharename, jobid, pjob);
1909
1910         if (pjob->spooled && pjob->sysjob != -1) 
1911         {
1912                 result = (*(current_printif->job_delete))(
1913                         PRINTERNAME(snum),
1914                         lp_lprmcommand(snum), 
1915                         pjob);
1916
1917                 /* Delete the tdb entry if the delete succeeded or the job hasn't
1918                    been spooled. */
1919
1920                 if (result == 0) {
1921                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1922                         int njobs = 1;
1923
1924                         if (!pdb)
1925                                 return False;
1926                         pjob_delete(sharename, jobid);
1927                         /* Ensure we keep a rough count of the number of total jobs... */
1928                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1929                         release_print_db(pdb);
1930                 }
1931         }
1932
1933         remove_from_jobs_changed( sharename, jobid );
1934
1935         return (result == 0);
1936 }
1937
1938 /****************************************************************************
1939  Return true if the current user owns the print job.
1940 ****************************************************************************/
1941
1942 static BOOL is_owner(struct current_user *user, const char *servicename,
1943                      uint32 jobid)
1944 {
1945         struct printjob *pjob = print_job_find(servicename, jobid);
1946         user_struct *vuser;
1947
1948         if (!pjob || !user)
1949                 return False;
1950
1951         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1952                 return strequal(pjob->user, vuser->user.smb_name);
1953         } else {
1954                 return strequal(pjob->user, uidtoname(user->ut.uid));
1955         }
1956 }
1957
1958 /****************************************************************************
1959  Delete a print job.
1960 ****************************************************************************/
1961
1962 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1963 {
1964         const char* sharename = lp_const_servicename( snum );
1965         struct printjob *pjob;
1966         BOOL    owner;
1967         char    *fname;
1968
1969         *errcode = WERR_OK;
1970                 
1971         owner = is_owner(user, lp_const_servicename(snum), jobid);
1972         
1973         /* Check access against security descriptor or whether the user
1974            owns their job. */
1975
1976         if (!owner && 
1977             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1978                 DEBUG(3, ("delete denied by security descriptor\n"));
1979                 *errcode = WERR_ACCESS_DENIED;
1980
1981                 /* BEGIN_ADMIN_LOG */
1982                 sys_adminlog( LOG_ERR, 
1983                               "Permission denied-- user not allowed to delete, \
1984 pause, or resume print job. User name: %s. Printer name: %s.",
1985                               uidtoname(user->ut.uid), PRINTERNAME(snum) );
1986                 /* END_ADMIN_LOG */
1987
1988                 return False;
1989         }
1990
1991         /* 
1992          * get the spooled filename of the print job
1993          * if this works, then the file has not been spooled
1994          * to the underlying print system.  Just delete the 
1995          * spool file & return.
1996          */
1997          
1998         if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1999         {
2000                 /* remove the spool file */
2001                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
2002                 if ( unlink( fname ) == -1 ) {
2003                         *errcode = map_werror_from_unix(errno);
2004                         return False;
2005                 }
2006         }
2007         
2008         if (!print_job_delete1(snum, jobid)) {
2009                 *errcode = WERR_ACCESS_DENIED;
2010                 return False;
2011         }
2012
2013         /* force update the database and say the delete failed if the
2014            job still exists */
2015
2016         print_queue_update(snum, True);
2017         
2018         pjob = print_job_find(sharename, jobid);
2019         if ( pjob && (pjob->status != LPQ_DELETING) )
2020                 *errcode = WERR_ACCESS_DENIED;
2021
2022         return (pjob == NULL );
2023 }
2024
2025 /****************************************************************************
2026  Pause a job.
2027 ****************************************************************************/
2028
2029 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2030 {
2031         const char* sharename = lp_const_servicename(snum);
2032         struct printjob *pjob;
2033         int ret = -1;
2034         struct printif *current_printif = get_printer_fns( snum );
2035
2036         pjob = print_job_find(sharename, jobid);
2037         
2038         if (!pjob || !user) {
2039                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2040                         (unsigned int)jobid ));
2041                 return False;
2042         }
2043
2044         if (!pjob->spooled || pjob->sysjob == -1) {
2045                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2046                         (int)pjob->sysjob, (unsigned int)jobid ));
2047                 return False;
2048         }
2049
2050         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2051             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2052                 DEBUG(3, ("pause denied by security descriptor\n"));
2053
2054                 /* BEGIN_ADMIN_LOG */
2055                 sys_adminlog( LOG_ERR, 
2056                         "Permission denied-- user not allowed to delete, \
2057 pause, or resume print job. User name: %s. Printer name: %s.",
2058                                 uidtoname(user->ut.uid), PRINTERNAME(snum) );
2059                 /* END_ADMIN_LOG */
2060
2061                 *errcode = WERR_ACCESS_DENIED;
2062                 return False;
2063         }
2064
2065         /* need to pause the spooled entry */
2066         ret = (*(current_printif->job_pause))(snum, pjob);
2067
2068         if (ret != 0) {
2069                 *errcode = WERR_INVALID_PARAM;
2070                 return False;
2071         }
2072
2073         /* force update the database */
2074         print_cache_flush(lp_const_servicename(snum));
2075
2076         /* Send a printer notify message */
2077
2078         notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
2079
2080         /* how do we tell if this succeeded? */
2081
2082         return True;
2083 }
2084
2085 /****************************************************************************
2086  Resume a job.
2087 ****************************************************************************/
2088
2089 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2090 {
2091         const char *sharename = lp_const_servicename(snum);
2092         struct printjob *pjob;
2093         int ret;
2094         struct printif *current_printif = get_printer_fns( snum );
2095
2096         pjob = print_job_find(sharename, jobid);
2097         
2098         if (!pjob || !user) {
2099                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2100                         (unsigned int)jobid ));
2101                 return False;
2102         }
2103
2104         if (!pjob->spooled || pjob->sysjob == -1) {
2105                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2106                         (int)pjob->sysjob, (unsigned int)jobid ));
2107                 return False;
2108         }
2109
2110         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2111             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2112                 DEBUG(3, ("resume denied by security descriptor\n"));
2113                 *errcode = WERR_ACCESS_DENIED;
2114
2115                 /* BEGIN_ADMIN_LOG */
2116                 sys_adminlog( LOG_ERR, 
2117                          "Permission denied-- user not allowed to delete, \
2118 pause, or resume print job. User name: %s. Printer name: %s.",
2119                         uidtoname(user->ut.uid), PRINTERNAME(snum) );
2120                 /* END_ADMIN_LOG */
2121                 return False;
2122         }
2123
2124         ret = (*(current_printif->job_resume))(snum, pjob);
2125
2126         if (ret != 0) {
2127                 *errcode = WERR_INVALID_PARAM;
2128                 return False;
2129         }
2130
2131         /* force update the database */
2132         print_cache_flush(lp_const_servicename(snum));
2133
2134         /* Send a printer notify message */
2135
2136         notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2137
2138         return True;
2139 }
2140
2141 /****************************************************************************
2142  Write to a print file.
2143 ****************************************************************************/
2144
2145 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2146 {
2147         const char* sharename = lp_const_servicename(snum);
2148         int return_code;
2149         struct printjob *pjob;
2150
2151         pjob = print_job_find(sharename, jobid);
2152
2153         if (!pjob)
2154                 return -1;
2155         /* don't allow another process to get this info - it is meaningless */
2156         if (pjob->pid != sys_getpid())
2157                 return -1;
2158
2159         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2160
2161         if (return_code>0) {
2162                 pjob->size += size;
2163                 pjob_store(sharename, jobid, pjob);
2164         }
2165         return return_code;
2166 }
2167
2168 /****************************************************************************
2169  Get the queue status - do not update if db is out of date.
2170 ****************************************************************************/
2171
2172 static int get_queue_status(const char* sharename, print_status_struct *status)
2173 {
2174         fstring keystr;
2175         TDB_DATA data;
2176         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2177         int len;
2178
2179         if (status) {
2180                 ZERO_STRUCTP(status);
2181         }
2182
2183         if (!pdb)
2184                 return 0;
2185
2186         if (status) {
2187                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2188                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2189                 if (data.dptr) {
2190                         if (data.dsize == sizeof(print_status_struct))
2191                                 /* this memcpy is ok since the status struct was 
2192                                    not packed before storing it in the tdb */
2193                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2194                         SAFE_FREE(data.dptr);
2195                 }
2196         }
2197         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2198         release_print_db(pdb);
2199         return (len == -1 ? 0 : len);
2200 }
2201
2202 /****************************************************************************
2203  Determine the number of jobs in a queue.
2204 ****************************************************************************/
2205
2206 int print_queue_length(int snum, print_status_struct *pstatus)
2207 {
2208         const char* sharename = lp_const_servicename( snum );
2209         print_status_struct status;
2210         int len;
2211
2212         ZERO_STRUCT( status );
2213  
2214         /* make sure the database is up to date */
2215         if (print_cache_expired(lp_const_servicename(snum), True))
2216                 print_queue_update(snum, False);
2217  
2218         /* also fetch the queue status */
2219         memset(&status, 0, sizeof(status));
2220         len = get_queue_status(sharename, &status);
2221
2222         if (pstatus)
2223                 *pstatus = status;
2224
2225         return len;
2226 }
2227
2228 /***************************************************************************
2229  Allocate a jobid. Hold the lock for as short a time as possible.
2230 ***************************************************************************/
2231
2232 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2233 {
2234         int i;
2235         uint32 jobid;
2236
2237         *pjobid = (uint32)-1;
2238
2239         for (i = 0; i < 3; i++) {
2240                 /* Lock the database - only wait 20 seconds. */
2241                 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
2242                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2243                         return False;
2244                 }
2245
2246                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2247                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2248                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2249                                         sharename));
2250                                 return False;
2251                         }
2252                         jobid = 0;
2253                 }
2254
2255                 jobid = NEXT_JOBID(jobid);
2256
2257                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2258                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2259                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2260                         return False;
2261                 }
2262
2263                 /* We've finished with the INFO/nextjob lock. */
2264                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2265                                 
2266                 if (!print_job_exists(sharename, jobid))
2267                         break;
2268         }
2269
2270         if (i > 2) {
2271                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2272                         sharename));
2273                 /* Probably full... */
2274                 errno = ENOSPC;
2275                 return False;
2276         }
2277
2278         /* Store a dummy placeholder. */
2279         {
2280                 TDB_DATA dum;
2281                 dum.dptr = NULL;
2282                 dum.dsize = 0;
2283                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2284                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2285                                 jobid ));
2286                         return False;
2287                 }
2288         }
2289
2290         *pjobid = jobid;
2291         return True;
2292 }
2293
2294 /***************************************************************************
2295  Append a jobid to the 'jobs changed' list.
2296 ***************************************************************************/
2297
2298 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2299 {
2300         TDB_DATA data;
2301         uint32 store_jobid;
2302
2303         SIVAL(&store_jobid, 0, jobid);
2304         data.dptr = (uint8 *)&store_jobid;
2305         data.dsize = 4;
2306
2307         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2308
2309         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2310                            data) == 0);
2311 }
2312
2313 /***************************************************************************
2314  Start spooling a job - return the jobid.
2315 ***************************************************************************/
2316
2317 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2318 {
2319         uint32 jobid;
2320         char *path;
2321         struct printjob pjob;
2322         user_struct *vuser;
2323         const char *sharename = lp_const_servicename(snum);
2324         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2325         int njobs;
2326
2327         errno = 0;
2328
2329         if (!pdb)
2330                 return (uint32)-1;
2331
2332         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2333                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2334                 release_print_db(pdb);
2335                 return (uint32)-1;
2336         }
2337
2338         if (!print_time_access_check(lp_servicename(snum))) {
2339                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2340                 release_print_db(pdb);
2341                 return (uint32)-1;
2342         }
2343
2344         path = lp_pathname(snum);
2345
2346         /* see if we have sufficient disk space */
2347         if (lp_minprintspace(snum)) {
2348                 SMB_BIG_UINT dspace, dsize;
2349                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2350                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2351                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
2352                         release_print_db(pdb);
2353                         errno = ENOSPC;
2354                         return (uint32)-1;
2355                 }
2356         }
2357
2358         /* for autoloaded printers, check that the printcap entry still exists */
2359         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2360                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2361                 release_print_db(pdb);
2362                 errno = ENOENT;
2363                 return (uint32)-1;
2364         }
2365
2366         /* Insure the maximum queue size is not violated */
2367         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2368                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2369                         sharename, njobs, lp_maxprintjobs(snum) ));
2370                 release_print_db(pdb);
2371                 errno = ENOSPC;
2372                 return (uint32)-1;
2373         }
2374
2375         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2376                 sharename, njobs, lp_maxprintjobs(snum) ));
2377
2378         if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2379                 goto fail;
2380
2381         /* create the database entry */
2382         
2383         ZERO_STRUCT(pjob);
2384         
2385         pjob.pid = sys_getpid();
2386         pjob.sysjob = -1;
2387         pjob.fd = -1;
2388         pjob.starttime = time(NULL);
2389         pjob.status = LPQ_SPOOLING;
2390         pjob.size = 0;
2391         pjob.spooled = False;
2392         pjob.smbjob = True;
2393         pjob.nt_devmode = nt_devmode;
2394         
2395         fstrcpy(pjob.jobname, jobname);
2396
2397         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2398                 fstrcpy(pjob.user, lp_printjob_username(snum));
2399                 standard_sub_basic(vuser->user.smb_name, vuser->user.domain, 
2400                                    pjob.user, sizeof(pjob.user)-1);
2401                 /* ensure NULL termination */ 
2402                 pjob.user[sizeof(pjob.user)-1] = '\0'; 
2403         } else {
2404                 fstrcpy(pjob.user, uidtoname(user->ut.uid));
2405         }
2406
2407         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2408
2409         /* we have a job entry - now create the spool file */
2410         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
2411                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2412         pjob.fd = smb_mkstemp(pjob.filename);
2413
2414         if (pjob.fd == -1) {
2415                 if (errno == EACCES) {
2416                         /* Common setup error, force a report. */
2417                         DEBUG(0, ("print_job_start: insufficient permissions \
2418 to open spool file %s.\n", pjob.filename));
2419                 } else {
2420                         /* Normal case, report at level 3 and above. */
2421                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2422                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2423                 }
2424                 goto fail;
2425         }
2426
2427         pjob_store(sharename, jobid, &pjob);
2428
2429         /* Update the 'jobs changed' entry used by print_queue_status. */
2430         add_to_jobs_changed(pdb, jobid);
2431
2432         /* Ensure we keep a rough count of the number of total jobs... */
2433         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2434
2435         release_print_db(pdb);
2436
2437         return jobid;
2438
2439  fail:
2440         if (jobid != -1)
2441                 pjob_delete(sharename, jobid);
2442
2443         release_print_db(pdb);
2444
2445         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2446         return (uint32)-1;
2447 }
2448
2449 /****************************************************************************
2450  Update the number of pages spooled to jobid
2451 ****************************************************************************/
2452
2453 void print_job_endpage(int snum, uint32 jobid)
2454 {
2455         const char* sharename = lp_const_servicename(snum);
2456         struct printjob *pjob;
2457
2458         pjob = print_job_find(sharename, jobid);
2459         if (!pjob)
2460                 return;
2461         /* don't allow another process to get this info - it is meaningless */
2462         if (pjob->pid != sys_getpid())
2463                 return;
2464
2465         pjob->page_count++;
2466         pjob_store(sharename, jobid, pjob);
2467 }
2468
2469 /****************************************************************************
2470  Print a file - called on closing the file. This spools the job.
2471  If normal close is false then we're tearing down the jobs - treat as an
2472  error.
2473 ****************************************************************************/
2474
2475 BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
2476 {
2477         const char* sharename = lp_const_servicename(snum);
2478         struct printjob *pjob;
2479         int ret;
2480         SMB_STRUCT_STAT sbuf;
2481         struct printif *current_printif = get_printer_fns( snum );
2482
2483         pjob = print_job_find(sharename, jobid);
2484
2485         if (!pjob)
2486                 return False;
2487
2488         if (pjob->spooled || pjob->pid != sys_getpid())
2489                 return False;
2490
2491         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
2492                                 (sys_fstat(pjob->fd, &sbuf) == 0)) {
2493                 pjob->size = sbuf.st_size;
2494                 close(pjob->fd);
2495                 pjob->fd = -1;
2496         } else {
2497
2498                 /* 
2499                  * Not a normal close or we couldn't stat the job file,
2500                  * so something has gone wrong. Cleanup.
2501                  */
2502                 close(pjob->fd);
2503                 pjob->fd = -1;
2504                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2505                 goto fail;
2506         }
2507
2508         /* Technically, this is not quite right. If the printer has a separator
2509          * page turned on, the NT spooler prints the separator page even if the
2510          * print job is 0 bytes. 010215 JRR */
2511         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2512                 /* don't bother spooling empty files or something being deleted. */
2513                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2514                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2515                 unlink(pjob->filename);
2516                 pjob_delete(sharename, jobid);
2517                 return True;
2518         }
2519
2520         pjob->smbjob = jobid;
2521
2522         ret = (*(current_printif->job_submit))(snum, pjob);
2523
2524         if (ret)
2525                 goto fail;
2526
2527         /* The print job has been sucessfully handed over to the back-end */
2528         
2529         pjob->spooled = True;
2530         pjob->status = LPQ_QUEUED;
2531         pjob_store(sharename, jobid, pjob);
2532         
2533         /* make sure the database is up to date */
2534         if (print_cache_expired(lp_const_servicename(snum), True))
2535                 print_queue_update(snum, False);
2536         
2537         return True;
2538
2539 fail:
2540
2541         /* The print job was not succesfully started. Cleanup */
2542         /* Still need to add proper error return propagation! 010122:JRR */
2543         unlink(pjob->filename);
2544         pjob_delete(sharename, jobid);
2545         return False;
2546 }
2547
2548 /****************************************************************************
2549  Get a snapshot of jobs in the system without traversing.
2550 ****************************************************************************/
2551
2552 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2553 {
2554         TDB_DATA data, cgdata;
2555         print_queue_struct *queue = NULL;
2556         uint32 qcount = 0;
2557         uint32 extra_count = 0;
2558         int total_count = 0;
2559         size_t len = 0;
2560         uint32 i;
2561         int max_reported_jobs = lp_max_reported_jobs(snum);
2562         BOOL ret = False;
2563         const char* sharename = lp_servicename(snum);
2564
2565         /* make sure the database is up to date */
2566         if (print_cache_expired(lp_const_servicename(snum), True))
2567                 print_queue_update(snum, False);
2568  
2569         *pcount = 0;
2570         *ppqueue = NULL;
2571
2572         ZERO_STRUCT(data);
2573         ZERO_STRUCT(cgdata);
2574
2575         /* Get the stored queue data. */
2576         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2577         
2578         if (data.dptr && data.dsize >= sizeof(qcount))
2579                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2580                 
2581         /* Get the changed jobs list. */
2582         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2583         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2584                 extra_count = cgdata.dsize/4;
2585
2586         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2587
2588         /* Allocate the queue size. */
2589         if (qcount == 0 && extra_count == 0)
2590                 goto out;
2591
2592         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2593                 goto out;
2594
2595         /* Retrieve the linearised queue data. */
2596
2597         for( i  = 0; i < qcount; i++) {
2598                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2599                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2600                                 &qjob,
2601                                 &qsize,
2602                                 &qpage_count,
2603                                 &qstatus,
2604                                 &qpriority,
2605                                 &qtime,
2606                                 queue[i].fs_user,
2607                                 queue[i].fs_file);
2608                 queue[i].job = qjob;
2609                 queue[i].size = qsize;
2610                 queue[i].page_count = qpage_count;
2611                 queue[i].status = qstatus;
2612                 queue[i].priority = qpriority;
2613                 queue[i].time = qtime;
2614         }
2615
2616         total_count = qcount;
2617
2618         /* Add in the changed jobids. */
2619         for( i  = 0; i < extra_count; i++) {
2620                 uint32 jobid;
2621                 struct printjob *pjob;
2622
2623                 jobid = IVAL(cgdata.dptr, i*4);
2624                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2625                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2626                 if (!pjob) {
2627                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2628                         remove_from_jobs_changed(sharename, jobid);
2629                         continue;
2630                 }
2631
2632                 queue[total_count].job = jobid;
2633                 queue[total_count].size = pjob->size;
2634                 queue[total_count].page_count = pjob->page_count;
2635                 queue[total_count].status = pjob->status;
2636                 queue[total_count].priority = 1;
2637                 queue[total_count].time = pjob->starttime;
2638                 fstrcpy(queue[total_count].fs_user, pjob->user);
2639                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2640                 total_count++;
2641         }
2642
2643         /* Sort the queue by submission time otherwise they are displayed
2644            in hash order. */
2645
2646         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2647
2648         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2649
2650         if (max_reported_jobs && total_count > max_reported_jobs)
2651                 total_count = max_reported_jobs;
2652
2653         *ppqueue = queue;
2654         *pcount = total_count;
2655
2656         ret = True;
2657
2658   out:
2659
2660         SAFE_FREE(data.dptr);
2661         SAFE_FREE(cgdata.dptr);
2662         return ret;
2663 }
2664
2665 /****************************************************************************
2666  Get a printer queue listing.
2667  set queue = NULL and status = NULL if you just want to update the cache
2668 ****************************************************************************/
2669
2670 int print_queue_status(int snum, 
2671                        print_queue_struct **ppqueue,
2672                        print_status_struct *status)
2673 {
2674         fstring keystr;
2675         TDB_DATA data, key;
2676         const char *sharename;
2677         struct tdb_print_db *pdb;
2678         int count = 0;
2679
2680         /* make sure the database is up to date */
2681
2682         if (print_cache_expired(lp_const_servicename(snum), True))
2683                 print_queue_update(snum, False);
2684
2685         /* return if we are done */
2686         if ( !ppqueue || !status )
2687                 return 0;
2688
2689         *ppqueue = NULL;
2690         sharename = lp_const_servicename(snum);
2691         pdb = get_print_db_byname(sharename);
2692
2693         if (!pdb)
2694                 return 0;
2695
2696         /*
2697          * Fetch the queue status.  We must do this first, as there may
2698          * be no jobs in the queue.
2699          */
2700
2701         ZERO_STRUCTP(status);
2702         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2703         key = string_tdb_data(keystr);
2704
2705         data = tdb_fetch(pdb->tdb, key);
2706         if (data.dptr) {
2707                 if (data.dsize == sizeof(*status)) {
2708                         /* this memcpy is ok since the status struct was 
2709                            not packed before storing it in the tdb */
2710                         memcpy(status, data.dptr, sizeof(*status));
2711                 }
2712                 SAFE_FREE(data.dptr);
2713         }
2714
2715         /*
2716          * Now, fetch the print queue information.  We first count the number
2717          * of entries, and then only retrieve the queue if necessary.
2718          */
2719
2720         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2721                 release_print_db(pdb);
2722                 return 0;
2723         }
2724
2725         release_print_db(pdb);
2726         return count;
2727 }
2728
2729 /****************************************************************************
2730  Pause a queue.
2731 ****************************************************************************/
2732
2733 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2734 {
2735         int ret;
2736         struct printif *current_printif = get_printer_fns( snum );
2737         
2738         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2739                 *errcode = WERR_ACCESS_DENIED;
2740                 return False;
2741         }
2742         
2743
2744         become_root();
2745                 
2746         ret = (*(current_printif->queue_pause))(snum);
2747
2748         unbecome_root();
2749                 
2750         if (ret != 0) {
2751                 *errcode = WERR_INVALID_PARAM;
2752                 return False;
2753         }
2754
2755         /* force update the database */
2756         print_cache_flush(lp_const_servicename(snum));
2757
2758         /* Send a printer notify message */
2759
2760         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2761
2762         return True;
2763 }
2764
2765 /****************************************************************************
2766  Resume a queue.
2767 ****************************************************************************/
2768
2769 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2770 {
2771         int ret;
2772         struct printif *current_printif = get_printer_fns( snum );
2773
2774         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2775                 *errcode = WERR_ACCESS_DENIED;
2776                 return False;
2777         }
2778         
2779         become_root();
2780                 
2781         ret = (*(current_printif->queue_resume))(snum);
2782
2783         unbecome_root();
2784                 
2785         if (ret != 0) {
2786                 *errcode = WERR_INVALID_PARAM;
2787                 return False;
2788         }
2789
2790         /* make sure the database is up to date */
2791         if (print_cache_expired(lp_const_servicename(snum), True))
2792                 print_queue_update(snum, True);
2793
2794         /* Send a printer notify message */
2795
2796         notify_printer_status(snum, PRINTER_STATUS_OK);
2797
2798         return True;
2799 }
2800
2801 /****************************************************************************
2802  Purge a queue - implemented by deleting all jobs that we can delete.
2803 ****************************************************************************/
2804
2805 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2806 {
2807         print_queue_struct *queue;
2808         print_status_struct status;
2809         int njobs, i;
2810         BOOL can_job_admin;
2811
2812         /* Force and update so the count is accurate (i.e. not a cached count) */
2813         print_queue_update(snum, True);
2814         
2815         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2816         njobs = print_queue_status(snum, &queue, &status);
2817         
2818         if ( can_job_admin )
2819                 become_root();
2820
2821         for (i=0;i<njobs;i++) {
2822                 BOOL owner = is_owner(user, lp_const_servicename(snum), queue[i].job);
2823
2824                 if (owner || can_job_admin) {
2825                         print_job_delete1(snum, queue[i].job);
2826                 }
2827         }
2828         
2829         if ( can_job_admin )
2830                 unbecome_root();
2831
2832         /* update the cache */
2833         print_queue_update( snum, True );
2834
2835         SAFE_FREE(queue);
2836
2837         return True;
2838 }