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