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