don't mistake pre-existing UNIX jobs for smb jobs; patch from SATOH Fumiyasu bug 770
[jra/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                 memcpy(&rap_jobid, data.dptr, sizeof(uint16));
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         memcpy(&rap_jobid, data.dptr, sizeof(uint16));
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 = (old_pj != NULL ? True : False);
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         memcpy(&jobid, key.dptr, sizeof(jobid));
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         memcpy(&updating_pid, data.dptr, sizeof(pid_t));
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                 memcpy(&ch_jobid, data.dptr + (i*4), 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                 memcpy(&ch_jobid, data.dptr + (i*4), 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                                 memcpy(status, data.dptr, sizeof(print_status_struct));
1758                         SAFE_FREE(data.dptr);
1759                 }
1760         }
1761         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1762         release_print_db(pdb);
1763         return (len == -1 ? 0 : len);
1764 }
1765
1766 /****************************************************************************
1767  Determine the number of jobs in a queue.
1768 ****************************************************************************/
1769
1770 int print_queue_length(int snum, print_status_struct *pstatus)
1771 {
1772         print_status_struct status;
1773         int len;
1774  
1775         /* make sure the database is up to date */
1776         if (print_cache_expired(snum))
1777                 print_queue_update(snum);
1778  
1779         /* also fetch the queue status */
1780         memset(&status, 0, sizeof(status));
1781         len = get_queue_status(snum, &status);
1782
1783         if (pstatus)
1784                 *pstatus = status;
1785
1786         return len;
1787 }
1788
1789 /***************************************************************************
1790  Allocate a jobid. Hold the lock for as short a time as possible.
1791 ***************************************************************************/
1792
1793 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1794 {
1795         int i;
1796         uint32 jobid;
1797
1798         *pjobid = (uint32)-1;
1799
1800         for (i = 0; i < 3; i++) {
1801                 /* Lock the database - only wait 20 seconds. */
1802                 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1803                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1804                         return False;
1805                 }
1806
1807                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1808                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1809                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1810                                                 printername ));
1811                                 return False;
1812                         }
1813                         jobid = 0;
1814                 }
1815
1816                 jobid = NEXT_JOBID(jobid);
1817
1818                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1819                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1820                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1821                         return False;
1822                 }
1823
1824                 /* We've finished with the INFO/nextjob lock. */
1825                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1826                                 
1827                 if (!print_job_exists(snum, jobid))
1828                         break;
1829         }
1830
1831         if (i > 2) {
1832                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1833                                 printername ));
1834                 /* Probably full... */
1835                 errno = ENOSPC;
1836                 return False;
1837         }
1838
1839         /* Store a dummy placeholder. */
1840         {
1841                 TDB_DATA dum;
1842                 dum.dptr = NULL;
1843                 dum.dsize = 0;
1844                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1845                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1846                                 jobid ));
1847                         return False;
1848                 }
1849         }
1850
1851         *pjobid = jobid;
1852         return True;
1853 }
1854
1855 /***************************************************************************
1856  Append a jobid to the 'jobs changed' list.
1857 ***************************************************************************/
1858
1859 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1860 {
1861         TDB_DATA data, key;
1862
1863         key.dptr = "INFO/jobs_changed";
1864         key.dsize = strlen(key.dptr);
1865         data.dptr = (char *)&jobid;
1866         data.dsize = 4;
1867
1868         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1869
1870         return (tdb_append(pdb->tdb, key, data) == 0);
1871 }
1872
1873 /***************************************************************************
1874  Start spooling a job - return the jobid.
1875 ***************************************************************************/
1876
1877 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1878 {
1879         uint32 jobid;
1880         char *path;
1881         struct printjob pjob;
1882         user_struct *vuser;
1883         const char *printername = lp_const_servicename(snum);
1884         struct tdb_print_db *pdb = get_print_db_byname(printername);
1885         int njobs;
1886
1887         errno = 0;
1888
1889         if (!pdb)
1890                 return (uint32)-1;
1891
1892         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1893                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1894                 release_print_db(pdb);
1895                 return (uint32)-1;
1896         }
1897
1898         if (!print_time_access_check(snum)) {
1899                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1900                 release_print_db(pdb);
1901                 return (uint32)-1;
1902         }
1903
1904         path = lp_pathname(snum);
1905
1906         /* see if we have sufficient disk space */
1907         if (lp_minprintspace(snum)) {
1908                 SMB_BIG_UINT dspace, dsize;
1909                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1910                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1911                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
1912                         release_print_db(pdb);
1913                         errno = ENOSPC;
1914                         return (uint32)-1;
1915                 }
1916         }
1917
1918         /* for autoloaded printers, check that the printcap entry still exists */
1919         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1920                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1921                 release_print_db(pdb);
1922                 errno = ENOENT;
1923                 return (uint32)-1;
1924         }
1925
1926         /* Insure the maximum queue size is not violated */
1927         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1928                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1929                         printername, njobs, lp_maxprintjobs(snum) ));
1930                 release_print_db(pdb);
1931                 errno = ENOSPC;
1932                 return (uint32)-1;
1933         }
1934
1935         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1936                         printername, njobs, lp_maxprintjobs(snum) ));
1937
1938         if (!allocate_print_jobid(pdb, snum, printername, &jobid))
1939                 goto fail;
1940
1941         /* create the database entry */
1942         
1943         ZERO_STRUCT(pjob);
1944         
1945         pjob.pid = local_pid;
1946         pjob.sysjob = -1;
1947         pjob.fd = -1;
1948         pjob.starttime = time(NULL);
1949         pjob.status = LPQ_SPOOLING;
1950         pjob.size = 0;
1951         pjob.spooled = False;
1952         pjob.smbjob = True;
1953         pjob.nt_devmode = nt_devmode;
1954         
1955         fstrcpy(pjob.jobname, jobname);
1956
1957         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1958                 fstrcpy(pjob.user, vuser->user.smb_name);
1959         } else {
1960                 fstrcpy(pjob.user, uidtoname(user->uid));
1961         }
1962
1963         fstrcpy(pjob.queuename, lp_const_servicename(snum));
1964
1965         /* we have a job entry - now create the spool file */
1966         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
1967                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
1968         pjob.fd = smb_mkstemp(pjob.filename);
1969
1970         if (pjob.fd == -1) {
1971                 if (errno == EACCES) {
1972                         /* Common setup error, force a report. */
1973                         DEBUG(0, ("print_job_start: insufficient permissions \
1974 to open spool file %s.\n", pjob.filename));
1975                 } else {
1976                         /* Normal case, report at level 3 and above. */
1977                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1978                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1979                 }
1980                 goto fail;
1981         }
1982
1983         pjob_store(snum, jobid, &pjob);
1984
1985         /* Update the 'jobs changed' entry used by print_queue_status. */
1986         add_to_jobs_changed(pdb, jobid);
1987
1988         /* Ensure we keep a rough count of the number of total jobs... */
1989         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
1990
1991         release_print_db(pdb);
1992
1993         return jobid;
1994
1995  fail:
1996         if (jobid != -1)
1997                 pjob_delete(snum, jobid);
1998
1999         release_print_db(pdb);
2000
2001         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2002         return (uint32)-1;
2003 }
2004
2005 /****************************************************************************
2006  Update the number of pages spooled to jobid
2007 ****************************************************************************/
2008
2009 void print_job_endpage(int snum, uint32 jobid)
2010 {
2011         struct printjob *pjob = print_job_find(snum, jobid);
2012         if (!pjob)
2013                 return;
2014         /* don't allow another process to get this info - it is meaningless */
2015         if (pjob->pid != local_pid)
2016                 return;
2017
2018         pjob->page_count++;
2019         pjob_store(snum, jobid, pjob);
2020 }
2021
2022 /****************************************************************************
2023  Print a file - called on closing the file. This spools the job.
2024  If normal close is false then we're tearing down the jobs - treat as an
2025  error.
2026 ****************************************************************************/
2027
2028 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2029 {
2030         struct printjob *pjob = print_job_find(snum, jobid);
2031         int ret;
2032         SMB_STRUCT_STAT sbuf;
2033
2034         if (!pjob)
2035                 return False;
2036
2037         if (pjob->spooled || pjob->pid != local_pid)
2038                 return False;
2039
2040         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2041                 pjob->size = sbuf.st_size;
2042                 close(pjob->fd);
2043                 pjob->fd = -1;
2044         } else {
2045
2046                 /* 
2047                  * Not a normal close or we couldn't stat the job file,
2048                  * so something has gone wrong. Cleanup.
2049                  */
2050                 close(pjob->fd);
2051                 pjob->fd = -1;
2052                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2053                 goto fail;
2054         }
2055
2056         /* Technically, this is not quite right. If the printer has a separator
2057          * page turned on, the NT spooler prints the separator page even if the
2058          * print job is 0 bytes. 010215 JRR */
2059         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2060                 /* don't bother spooling empty files or something being deleted. */
2061                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2062                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2063                 unlink(pjob->filename);
2064                 pjob_delete(snum, jobid);
2065                 return True;
2066         }
2067
2068         pjob->smbjob = jobid;
2069
2070         ret = (*(current_printif->job_submit))(snum, pjob);
2071
2072         if (ret)
2073                 goto fail;
2074
2075         /* The print job has been sucessfully handed over to the back-end */
2076         
2077         pjob->spooled = True;
2078         pjob->status = LPQ_QUEUED;
2079         pjob_store(snum, jobid, pjob);
2080         
2081         /* make sure the database is up to date */
2082         if (print_cache_expired(snum))
2083                 print_queue_update(snum);
2084         
2085         return True;
2086
2087 fail:
2088
2089         /* The print job was not succesfully started. Cleanup */
2090         /* Still need to add proper error return propagation! 010122:JRR */
2091         unlink(pjob->filename);
2092         pjob_delete(snum, jobid);
2093         remove_from_jobs_changed(snum, jobid);
2094         return False;
2095 }
2096
2097 /****************************************************************************
2098  Get a snapshot of jobs in the system without traversing.
2099 ****************************************************************************/
2100
2101 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2102 {
2103         TDB_DATA data, key, cgdata;
2104         print_queue_struct *queue = NULL;
2105         uint32 qcount = 0;
2106         uint32 extra_count = 0;
2107         int total_count = 0;
2108         size_t len = 0;
2109         uint32 i;
2110         int max_reported_jobs = lp_max_reported_jobs(snum);
2111         BOOL ret = False;
2112
2113         /* make sure the database is up to date */
2114         if (print_cache_expired(snum))
2115                 print_queue_update(snum);
2116  
2117         *pcount = 0;
2118         *ppqueue = NULL;
2119
2120         ZERO_STRUCT(data);
2121         ZERO_STRUCT(cgdata);
2122         key.dptr = "INFO/linear_queue_array";
2123         key.dsize = strlen(key.dptr);
2124
2125         /* Get the stored queue data. */
2126         data = tdb_fetch(pdb->tdb, key);
2127
2128         if (data.dptr == NULL || data.dsize < 4)
2129                 qcount = 0;
2130         else
2131                 memcpy(&qcount, data.dptr, 4);
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         len = 0;
2152         for( i  = 0; i < qcount; i++) {
2153                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2154                 len += tdb_unpack(data.dptr + 4 + 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                 memcpy(&jobid, &cgdata.dptr[i*4], 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                         memcpy(status, data.dptr, sizeof(*status));
2264                 }
2265                 SAFE_FREE(data.dptr);
2266         }
2267
2268         /*
2269          * Now, fetch the print queue information.  We first count the number
2270          * of entries, and then only retrieve the queue if necessary.
2271          */
2272
2273         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2274                 release_print_db(pdb);
2275                 return 0;
2276         }
2277
2278         release_print_db(pdb);
2279         return count;
2280 }
2281
2282 /****************************************************************************
2283  Pause a queue.
2284 ****************************************************************************/
2285
2286 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2287 {
2288         int ret;
2289         
2290         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2291                 *errcode = WERR_ACCESS_DENIED;
2292                 return False;
2293         }
2294
2295         ret = (*(current_printif->queue_pause))(snum);
2296
2297         if (ret != 0) {
2298                 *errcode = WERR_INVALID_PARAM;
2299                 return False;
2300         }
2301
2302         /* force update the database */
2303         print_cache_flush(snum);
2304
2305         /* Send a printer notify message */
2306
2307         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2308
2309         return True;
2310 }
2311
2312 /****************************************************************************
2313  Resume a queue.
2314 ****************************************************************************/
2315
2316 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2317 {
2318         int ret;
2319
2320         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2321                 *errcode = WERR_ACCESS_DENIED;
2322                 return False;
2323         }
2324
2325         ret = (*(current_printif->queue_resume))(snum);
2326
2327         if (ret != 0) {
2328                 *errcode = WERR_INVALID_PARAM;
2329                 return False;
2330         }
2331
2332         /* make sure the database is up to date */
2333         if (print_cache_expired(snum))
2334                 print_queue_update(snum);
2335
2336         /* Send a printer notify message */
2337
2338         notify_printer_status(snum, PRINTER_STATUS_OK);
2339
2340         return True;
2341 }
2342
2343 /****************************************************************************
2344  Purge a queue - implemented by deleting all jobs that we can delete.
2345 ****************************************************************************/
2346
2347 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2348 {
2349         print_queue_struct *queue;
2350         print_status_struct status;
2351         int njobs, i;
2352         BOOL can_job_admin;
2353
2354         /* Force and update so the count is accurate (i.e. not a cached count) */
2355         print_queue_update(snum);
2356         
2357         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2358         njobs = print_queue_status(snum, &queue, &status);
2359
2360         for (i=0;i<njobs;i++) {
2361                 BOOL owner = is_owner(user, snum, queue[i].job);
2362
2363                 if (owner || can_job_admin) {
2364                         print_job_delete1(snum, queue[i].job);
2365                 }
2366         }
2367
2368         SAFE_FREE(queue);
2369
2370         return True;
2371 }