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