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