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