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