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