Subtle changes to message handling after ENUMJOBS.
[abartlet/samba.git/.git] / source / printing / printing.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "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         pj.smbjob = (old_pj != NULL ? True : False);
616         fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
617         if (jobid < UNIX_JOB_START)
618                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
619         else
620                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
621         fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
622         fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
623
624         pjob_store(snum, jobid, &pj);
625 }
626
627
628 struct traverse_struct {
629         print_queue_struct *queue;
630         int qcount, snum, maxcount, total_jobs;
631         time_t lpq_time;
632 };
633
634 /****************************************************************************
635  Utility fn to delete any jobs that are no longer active.
636 ****************************************************************************/
637
638 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
639 {
640         struct traverse_struct *ts = (struct traverse_struct *)state;
641         struct printjob pjob;
642         uint32 jobid;
643         int i;
644
645         if (  key.dsize != sizeof(jobid) )
646                 return 0;
647                 
648         memcpy(&jobid, key.dptr, sizeof(jobid));
649         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
650                 return 0;
651         free_nt_devicemode( &pjob.nt_devmode );
652
653
654         if (ts->snum != lp_servicenumber(pjob.queuename)) {
655                 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
656                 return 0;
657         }
658
659         if (!pjob.smbjob) {
660                 /* remove a unix job if it isn't in the system queue any more */
661
662                 for (i=0;i<ts->qcount;i++) {
663                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
664                         if (jobid == u_jobid)
665                                 break;
666                 }
667                 if (i == ts->qcount) {
668                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
669                                                 (unsigned int)jobid ));
670                         pjob_delete(ts->snum, jobid);
671                 } else
672                         ts->total_jobs++;
673                 return 0;
674         }
675
676         /* maybe it hasn't been spooled yet */
677         if (!pjob.spooled) {
678                 /* if a job is not spooled and the process doesn't
679                    exist then kill it. This cleans up after smbd
680                    deaths */
681                 if (!process_exists(pjob.pid)) {
682                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
683                                                 (unsigned int)jobid, (unsigned int)pjob.pid ));
684                         pjob_delete(ts->snum, jobid);
685                 } else
686                         ts->total_jobs++;
687                 return 0;
688         }
689
690         for (i=0;i<ts->qcount;i++) {
691                 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
692                 if (jobid == curr_jobid)
693                         break;
694         }
695         
696         /* The job isn't in the system queue - we have to assume it has
697            completed, so delete the database entry. */
698
699         if (i == ts->qcount) {
700
701                 /* A race can occur between the time a job is spooled and
702                    when it appears in the lpq output.  This happens when
703                    the job is added to printing.tdb when another smbd
704                    running print_queue_update() has completed a lpq and
705                    is currently traversing the printing tdb and deleting jobs.
706                    Don't delete the job if it was submitted after the lpq_time. */
707
708                 if (pjob.starttime < ts->lpq_time) {
709                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
710                                                 (unsigned int)jobid,
711                                                 (unsigned int)pjob.starttime,
712                                                 (unsigned int)ts->lpq_time ));
713                         pjob_delete(ts->snum, jobid);
714                 } else
715                         ts->total_jobs++;
716         }
717         else
718                 ts->total_jobs++;
719
720         return 0;
721 }
722
723 /****************************************************************************
724  Check if the print queue has been updated recently enough.
725 ****************************************************************************/
726
727 static void print_cache_flush(int snum)
728 {
729         fstring key;
730         const char *printername = lp_const_servicename(snum);
731         struct tdb_print_db *pdb = get_print_db_byname(printername);
732
733         if (!pdb)
734                 return;
735         slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
736         tdb_store_int32(pdb->tdb, key, -1);
737         release_print_db(pdb);
738 }
739
740 /****************************************************************************
741  Check if someone already thinks they are doing the update.
742 ****************************************************************************/
743
744 static pid_t get_updating_pid(fstring printer_name)
745 {
746         fstring keystr;
747         TDB_DATA data, key;
748         pid_t updating_pid;
749         struct tdb_print_db *pdb = get_print_db_byname(printer_name);
750
751         if (!pdb)
752                 return (pid_t)-1;
753         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
754         key.dptr = keystr;
755         key.dsize = strlen(keystr);
756
757         data = tdb_fetch(pdb->tdb, key);
758         release_print_db(pdb);
759         if (!data.dptr || data.dsize != sizeof(pid_t)) {
760                 SAFE_FREE(data.dptr);
761                 return (pid_t)-1;
762         }
763
764         memcpy(&updating_pid, data.dptr, sizeof(pid_t));
765         SAFE_FREE(data.dptr);
766
767         if (process_exists(updating_pid))
768                 return updating_pid;
769
770         return (pid_t)-1;
771 }
772
773 /****************************************************************************
774  Set the fact that we're doing the update, or have finished doing the update
775  in the tdb.
776 ****************************************************************************/
777
778 static void set_updating_pid(const fstring printer_name, BOOL delete)
779 {
780         fstring keystr;
781         TDB_DATA key;
782         TDB_DATA data;
783         pid_t updating_pid = sys_getpid();
784         struct tdb_print_db *pdb = get_print_db_byname(printer_name);
785
786         if (!pdb)
787                 return;
788
789         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
790         key.dptr = keystr;
791         key.dsize = strlen(keystr);
792
793         if (delete) {
794                 tdb_delete(pdb->tdb, key);
795                 release_print_db(pdb);
796                 return;
797         }
798         
799         data.dptr = (void *)&updating_pid;
800         data.dsize = sizeof(pid_t);
801
802         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
803         release_print_db(pdb);
804 }
805
806 /****************************************************************************
807  Sort print jobs by submittal time.
808 ****************************************************************************/
809
810 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
811 {
812         /* Silly cases */
813
814         if (!j1 && !j2)
815                 return 0;
816         if (!j1)
817                 return -1;
818         if (!j2)
819                 return 1;
820
821         /* Sort on job start time */
822
823         if (j1->time == j2->time)
824                 return 0;
825         return (j1->time > j2->time) ? 1 : -1;
826 }
827
828 /****************************************************************************
829  Store the sorted queue representation for later portmon retrieval.
830 ****************************************************************************/
831
832 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
833 {
834         TDB_DATA data, key;
835         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
836         print_queue_struct *queue = pts->queue;
837         size_t len;
838         size_t i;
839         uint qcount;
840
841         if (max_reported_jobs < pts->qcount)
842                 pts->qcount = max_reported_jobs;
843         qcount = pts->qcount;
844
845         /* Work out the size. */
846         data.dsize = 0;
847         data.dsize += tdb_pack(NULL, 0, NULL, "d", qcount);
848
849         for (i = 0; i < pts->qcount; i++) {
850                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
851                                 (uint32)queue[i].job,
852                                 (uint32)queue[i].size,
853                                 (uint32)queue[i].page_count,
854                                 (uint32)queue[i].status,
855                                 (uint32)queue[i].priority,
856                                 (uint32)queue[i].time,
857                                 queue[i].fs_user,
858                                 queue[i].fs_file);
859         }
860
861         if ((data.dptr = malloc(data.dsize)) == NULL)
862                 return;
863
864         len = 0;
865         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
866         for (i = 0; i < pts->qcount; i++) {
867                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
868                                 (uint32)queue[i].job,
869                                 (uint32)queue[i].size,
870                                 (uint32)queue[i].page_count,
871                                 (uint32)queue[i].status,
872                                 (uint32)queue[i].priority,
873                                 (uint32)queue[i].time,
874                                 queue[i].fs_user,
875                                 queue[i].fs_file);
876         }
877
878         key.dptr = "INFO/linear_queue_array";
879         key.dsize = strlen(key.dptr);
880         tdb_store(pdb->tdb, key, data, TDB_REPLACE);
881         return;
882 }
883
884 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
885 {
886         TDB_DATA data, key;
887
888         key.dptr = "INFO/jobs_changed";
889         key.dsize = strlen(key.dptr);
890         ZERO_STRUCT(data);
891
892         data = tdb_fetch(pdb->tdb, key);
893         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
894                 SAFE_FREE(data.dptr);
895                 ZERO_STRUCT(data);
896         }
897
898         return data;
899 }
900
901 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
902 {
903         unsigned int i;
904         unsigned int job_count = data.dsize / 4;
905
906         for (i = 0; i < job_count; i++) {
907                 uint32 ch_jobid;
908
909                 memcpy(&ch_jobid, data.dptr + (i*4), 4);
910                 if (ch_jobid == jobid)
911                         remove_from_jobs_changed(snum, jobid);
912         }
913 }
914
915 /****************************************************************************
916  Update the internal database from the system print queue for a queue.
917 ****************************************************************************/
918
919 static void print_queue_update(int snum)
920 {
921         int i, qcount;
922         print_queue_struct *queue = NULL;
923         print_status_struct status;
924         print_status_struct old_status;
925         struct printjob *pjob;
926         struct traverse_struct tstruct;
927         fstring keystr, printer_name, cachestr;
928         TDB_DATA data, key;
929         TDB_DATA jcdata;
930         struct tdb_print_db *pdb;
931
932         fstrcpy(printer_name, lp_const_servicename(snum));
933         pdb = get_print_db_byname(printer_name);
934         if (!pdb)
935                 return;
936
937         /*
938          * Check to see if someone else is doing this update.
939          * This is essentially a mutex on the update.
940          */
941
942         if (get_updating_pid(printer_name) != -1) {
943                 release_print_db(pdb);
944                 return;
945         }
946
947         /* Lock the queue for the database update */
948
949         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
950         /* Only wait 10 seconds for this. */
951         if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
952                 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
953                 release_print_db(pdb);
954                 return;
955         }
956
957         /*
958          * Ensure that no one else got in here.
959          * If the updating pid is still -1 then we are
960          * the winner.
961          */
962
963         if (get_updating_pid(printer_name) != -1) {
964                 /*
965                  * Someone else is doing the update, exit.
966                  */
967                 tdb_unlock_bystring(pdb->tdb, keystr);
968                 release_print_db(pdb);
969                 return;
970         }
971
972         /*
973          * We're going to do the update ourselves.
974          */
975
976         /* Tell others we're doing the update. */
977         set_updating_pid(printer_name, False);
978
979         /*
980          * Allow others to enter and notice we're doing
981          * the update.
982          */
983
984         tdb_unlock_bystring(pdb->tdb, keystr);
985
986         /*
987          * Update the cache time FIRST ! Stops others even
988          * attempting to get the lock and doing this
989          * if the lpq takes a long time.
990          */
991
992         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
993         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
994
995         /* get the current queue using the appropriate interface */
996         ZERO_STRUCT(status);
997
998         qcount = (*(current_printif->queue_get))(snum, &queue, &status);
999
1000         DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1001                 "s" : "", printer_name));
1002
1003         /* Sort the queue by submission time otherwise they are displayed
1004            in hash order. */
1005
1006         qsort(queue, qcount, sizeof(print_queue_struct),
1007               QSORT_CAST(printjob_comp));
1008
1009         /*
1010           any job in the internal database that is marked as spooled
1011           and doesn't exist in the system queue is considered finished
1012           and removed from the database
1013
1014           any job in the system database but not in the internal database 
1015           is added as a unix job
1016
1017           fill in any system job numbers as we go
1018         */
1019
1020         jcdata = get_jobs_changed_data(pdb);
1021
1022         for (i=0; i<qcount; i++) {
1023                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1024
1025                 if (jobid == (uint32)-1) {
1026                         /* assume its a unix print job */
1027                         print_unix_job(snum, &queue[i], jobid);
1028                         continue;
1029                 }
1030
1031                 /* we have an active SMB print job - update its status */
1032                 pjob = print_job_find(snum, jobid);
1033                 if (!pjob) {
1034                         /* err, somethings wrong. Probably smbd was restarted
1035                            with jobs in the queue. All we can do is treat them
1036                            like unix jobs. Pity. */
1037                         print_unix_job(snum, &queue[i], jobid);
1038                         continue;
1039                 }
1040
1041                 pjob->sysjob = queue[i].job;
1042                 pjob->status = queue[i].status;
1043                 pjob_store(snum, jobid, pjob);
1044                 check_job_changed(snum, jcdata, jobid);
1045         }
1046
1047         SAFE_FREE(jcdata.dptr);
1048
1049         /* now delete any queued entries that don't appear in the
1050            system queue */
1051         tstruct.queue = queue;
1052         tstruct.qcount = qcount;
1053         tstruct.snum = snum;
1054         tstruct.total_jobs = 0;
1055         tstruct.lpq_time = time(NULL);
1056
1057         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1058
1059         /* Store the linearised queue, max jobs only. */
1060         store_queue_struct(pdb, &tstruct);
1061
1062         SAFE_FREE(tstruct.queue);
1063
1064         DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1065                                 printer_name, tstruct.total_jobs ));
1066
1067         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1068
1069         get_queue_status(snum, &old_status);
1070         if (old_status.qcount != qcount)
1071                 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1072                                         old_status.qcount, qcount, printer_name ));
1073
1074         /* store the new queue status structure */
1075         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1076         key.dptr = keystr;
1077         key.dsize = strlen(keystr);
1078
1079         status.qcount = qcount;
1080         data.dptr = (void *)&status;
1081         data.dsize = sizeof(status);
1082         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1083
1084         /*
1085          * Update the cache time again. We want to do this call
1086          * as little as possible...
1087          */
1088
1089         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1090         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1091
1092         /* Delete our pid from the db. */
1093         set_updating_pid(printer_name, True);
1094         release_print_db(pdb);
1095 }
1096
1097 /****************************************************************************
1098  Create/Update an entry in the print tdb that will allow us to send notify
1099  updates only to interested smbd's. 
1100 ****************************************************************************/
1101
1102 BOOL print_notify_register_pid(int snum)
1103 {
1104         TDB_DATA data;
1105         struct tdb_print_db *pdb = NULL;
1106         TDB_CONTEXT *tdb = NULL;
1107         const char *printername;
1108         uint32 mypid = (uint32)sys_getpid();
1109         BOOL ret = False;
1110         size_t i;
1111
1112         /* if (snum == -1), then the change notify request was
1113            on a print server handle and we need to register on
1114            all print queus */
1115            
1116         if (snum == -1) 
1117         {
1118                 int num_services = lp_numservices();
1119                 int idx;
1120                 
1121                 for ( idx=0; idx<num_services; idx++ ) {
1122                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1123                                 print_notify_register_pid(idx);
1124                 }
1125                 
1126                 return True;
1127         }
1128         else /* register for a specific printer */
1129         {
1130                 printername = lp_const_servicename(snum);
1131                 pdb = get_print_db_byname(printername);
1132                 if (!pdb)
1133                         return False;
1134                 tdb = pdb->tdb;
1135         }
1136
1137         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1138                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1139                                         printername));
1140                 if (pdb)
1141                         release_print_db(pdb);
1142                 return False;
1143         }
1144
1145         data = get_printer_notify_pid_list( tdb, printername, True );
1146
1147         /* Add ourselves and increase the refcount. */
1148
1149         for (i = 0; i < data.dsize; i += 8) {
1150                 if (IVAL(data.dptr,i) == mypid) {
1151                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1152                         SIVAL(data.dptr, i+4, new_refcount);
1153                         break;
1154                 }
1155         }
1156
1157         if (i == data.dsize) {
1158                 /* We weren't in the list. Realloc. */
1159                 data.dptr = Realloc(data.dptr, data.dsize + 8);
1160                 if (!data.dptr) {
1161                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1162                                                 printername));
1163                         goto done;
1164                 }
1165                 data.dsize += 8;
1166                 SIVAL(data.dptr,data.dsize - 8,mypid);
1167                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1168         }
1169
1170         /* Store back the record. */
1171         if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1172                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1173 list for printer %s\n", printername));
1174                 goto done;
1175         }
1176
1177         ret = True;
1178
1179  done:
1180
1181         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1182         if (pdb)
1183                 release_print_db(pdb);
1184         SAFE_FREE(data.dptr);
1185         return ret;
1186 }
1187
1188 /****************************************************************************
1189  Update an entry in the print tdb that will allow us to send notify
1190  updates only to interested smbd's. 
1191 ****************************************************************************/
1192
1193 BOOL print_notify_deregister_pid(int snum)
1194 {
1195         TDB_DATA data;
1196         struct tdb_print_db *pdb = NULL;
1197         TDB_CONTEXT *tdb = NULL;
1198         const char *printername;
1199         uint32 mypid = (uint32)sys_getpid();
1200         size_t i;
1201         BOOL ret = False;
1202
1203         /* if ( snum == -1 ), we are deregister a print server handle
1204            which means to deregister on all print queues */
1205            
1206         if (snum == -1) 
1207         {
1208                 int num_services = lp_numservices();
1209                 int idx;
1210                 
1211                 for ( idx=0; idx<num_services; idx++ ) {
1212                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1213                                 print_notify_deregister_pid(idx);
1214                 }
1215                 
1216                 return True;
1217         }
1218         else /* deregister a specific printer */
1219         {
1220                 printername = lp_const_servicename(snum);
1221                 pdb = get_print_db_byname(printername);
1222                 if (!pdb)
1223                         return False;
1224                 tdb = pdb->tdb;
1225         }
1226
1227         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1228                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1229 printer %s database\n", printername));
1230                 if (pdb)
1231                         release_print_db(pdb);
1232                 return False;
1233         }
1234
1235         data = get_printer_notify_pid_list( tdb, printername, True );
1236
1237         /* Reduce refcount. Remove ourselves if zero. */
1238
1239         for (i = 0; i < data.dsize; ) {
1240                 if (IVAL(data.dptr,i) == mypid) {
1241                         uint32 refcount = IVAL(data.dptr, i+4);
1242
1243                         refcount--;
1244
1245                         if (refcount == 0) {
1246                                 if (data.dsize - i > 8)
1247                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1248                                 data.dsize -= 8;
1249                                 continue;
1250                         }
1251                         SIVAL(data.dptr, i+4, refcount);
1252                 }
1253
1254                 i += 8;
1255         }
1256
1257         if (data.dsize == 0)
1258                 SAFE_FREE(data.dptr);
1259
1260         /* Store back the record. */
1261         if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1262                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1263 list for printer %s\n", printername));
1264                 goto done;
1265         }
1266
1267         ret = True;
1268
1269   done:
1270
1271         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1272         if (pdb)
1273                 release_print_db(pdb);
1274         SAFE_FREE(data.dptr);
1275         return ret;
1276 }
1277
1278 /****************************************************************************
1279  Check if a jobid is valid. It is valid if it exists in the database.
1280 ****************************************************************************/
1281
1282 BOOL print_job_exists(int snum, uint32 jobid)
1283 {
1284         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1285         BOOL ret;
1286
1287         if (!pdb)
1288                 return False;
1289         ret = tdb_exists(pdb->tdb, print_key(jobid));
1290         release_print_db(pdb);
1291         return ret;
1292 }
1293
1294 /****************************************************************************
1295  Give the fd used for a jobid.
1296 ****************************************************************************/
1297
1298 int print_job_fd(int snum, uint32 jobid)
1299 {
1300         struct printjob *pjob = print_job_find(snum, jobid);
1301         if (!pjob)
1302                 return -1;
1303         /* don't allow another process to get this info - it is meaningless */
1304         if (pjob->pid != local_pid)
1305                 return -1;
1306         return pjob->fd;
1307 }
1308
1309 /****************************************************************************
1310  Give the filename used for a jobid.
1311  Only valid for the process doing the spooling and when the job
1312  has not been spooled.
1313 ****************************************************************************/
1314
1315 char *print_job_fname(int snum, uint32 jobid)
1316 {
1317         struct printjob *pjob = print_job_find(snum, jobid);
1318         if (!pjob || pjob->spooled || pjob->pid != local_pid)
1319                 return NULL;
1320         return pjob->filename;
1321 }
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 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1331 {
1332         struct printjob *pjob = print_job_find(snum, jobid);
1333         
1334         if ( !pjob )
1335                 return NULL;
1336                 
1337         return pjob->nt_devmode;
1338 }
1339
1340 /****************************************************************************
1341  Set the place in the queue for a job.
1342 ****************************************************************************/
1343
1344 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1345 {
1346         DEBUG(2,("print_job_set_place not implemented yet\n"));
1347         return False;
1348 }
1349
1350 /****************************************************************************
1351  Set the name of a job. Only possible for owner.
1352 ****************************************************************************/
1353
1354 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1355 {
1356         struct printjob *pjob = print_job_find(snum, jobid);
1357         if (!pjob || pjob->pid != local_pid)
1358                 return False;
1359
1360         fstrcpy(pjob->jobname, name);
1361         return pjob_store(snum, jobid, pjob);
1362 }
1363
1364 /***************************************************************************
1365  Remove a jobid from the 'jobs changed' list.
1366 ***************************************************************************/
1367
1368 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1369 {
1370         const char *printername = lp_const_servicename(snum);
1371         struct tdb_print_db *pdb = get_print_db_byname(printername);
1372         TDB_DATA data, key;
1373         size_t job_count, i;
1374         BOOL ret = False;
1375         BOOL gotlock = False;
1376
1377         key.dptr = "INFO/jobs_changed";
1378         key.dsize = strlen(key.dptr);
1379         ZERO_STRUCT(data);
1380
1381         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1382                 goto out;
1383
1384         gotlock = True;
1385
1386         data = tdb_fetch(pdb->tdb, key);
1387
1388         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1389                 goto out;
1390
1391         job_count = data.dsize / 4;
1392         for (i = 0; i < job_count; i++) {
1393                 uint32 ch_jobid;
1394
1395                 memcpy(&ch_jobid, data.dptr + (i*4), 4);
1396                 if (ch_jobid == jobid) {
1397                         if (i < job_count -1 )
1398                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1399                         data.dsize -= 4;
1400                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1401                                 goto out;
1402                         break;
1403                 }
1404         }
1405
1406         ret = True;
1407   out:
1408
1409         if (gotlock)
1410                 tdb_chainunlock(pdb->tdb, key);
1411         SAFE_FREE(data.dptr);
1412         release_print_db(pdb);
1413         if (ret)
1414                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1415         else
1416                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1417         return ret;
1418 }
1419
1420 /****************************************************************************
1421  Delete a print job - don't update queue.
1422 ****************************************************************************/
1423
1424 static BOOL print_job_delete1(int snum, uint32 jobid)
1425 {
1426         struct printjob *pjob = print_job_find(snum, jobid);
1427         int result = 0;
1428
1429         if (!pjob)
1430                 return False;
1431
1432         /*
1433          * If already deleting just return.
1434          */
1435
1436         if (pjob->status == LPQ_DELETING)
1437                 return True;
1438
1439         /* Hrm - we need to be able to cope with deleting a job before it
1440            has reached the spooler. */
1441
1442         if (pjob->sysjob == -1) {
1443                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1444         }
1445
1446         /* Set the tdb entry to be deleting. */
1447
1448         pjob->status = LPQ_DELETING;
1449         pjob_store(snum, jobid, pjob);
1450
1451         if (pjob->spooled && pjob->sysjob != -1)
1452                 result = (*(current_printif->job_delete))(snum, pjob);
1453         else
1454                 remove_from_jobs_changed(snum, jobid);
1455
1456         /* Delete the tdb entry if the delete suceeded or the job hasn't
1457            been spooled. */
1458
1459         if (result == 0) {
1460                 const char *printername = lp_const_servicename(snum);
1461                 struct tdb_print_db *pdb = get_print_db_byname(printername);
1462                 int njobs = 1;
1463
1464                 if (!pdb)
1465                         return False;
1466                 pjob_delete(snum, jobid);
1467                 /* Ensure we keep a rough count of the number of total jobs... */
1468                 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1469                 release_print_db(pdb);
1470         }
1471
1472         return (result == 0);
1473 }
1474
1475 /****************************************************************************
1476  Return true if the current user owns the print job.
1477 ****************************************************************************/
1478
1479 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1480 {
1481         struct printjob *pjob = print_job_find(snum, jobid);
1482         user_struct *vuser;
1483
1484         if (!pjob || !user)
1485                 return False;
1486
1487         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1488                 return strequal(pjob->user, vuser->user.smb_name);
1489         } else {
1490                 return strequal(pjob->user, uidtoname(user->uid));
1491         }
1492 }
1493
1494 /****************************************************************************
1495  Delete a print job.
1496 ****************************************************************************/
1497
1498 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1499 {
1500         BOOL    owner, deleted;
1501         char    *fname;
1502
1503         *errcode = WERR_OK;
1504                 
1505         owner = is_owner(user, snum, jobid);
1506         
1507         /* Check access against security descriptor or whether the user
1508            owns their job. */
1509
1510         if (!owner && 
1511             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1512                 DEBUG(3, ("delete denied by security descriptor\n"));
1513                 *errcode = WERR_ACCESS_DENIED;
1514
1515                 /* BEGIN_ADMIN_LOG */
1516                 sys_adminlog( LOG_ERR, 
1517                               "Permission denied-- user not allowed to delete, \
1518 pause, or resume print job. User name: %s. Printer name: %s.",
1519                               uidtoname(user->uid), PRINTERNAME(snum) );
1520                 /* END_ADMIN_LOG */
1521
1522                 return False;
1523         }
1524
1525         /* 
1526          * get the spooled filename of the print job
1527          * if this works, then the file has not been spooled
1528          * to the underlying print system.  Just delete the 
1529          * spool file & return.
1530          */
1531          
1532         if ( (fname = print_job_fname( snum, jobid )) != NULL )
1533         {
1534                 /* remove the spool file */
1535                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1536                 if ( unlink( fname ) == -1 ) {
1537                         *errcode = map_werror_from_unix(errno);
1538                         return False;
1539                 }
1540                 
1541                 return True;
1542         }
1543         
1544         if (!print_job_delete1(snum, jobid)) {
1545                 *errcode = WERR_ACCESS_DENIED;
1546                 return False;
1547         }
1548
1549         /* force update the database and say the delete failed if the
1550            job still exists */
1551
1552         print_queue_update(snum);
1553         
1554         deleted = !print_job_exists(snum, jobid);
1555         if ( !deleted )
1556                 *errcode = WERR_ACCESS_DENIED;
1557
1558         return deleted;
1559 }
1560
1561 /****************************************************************************
1562  Pause a job.
1563 ****************************************************************************/
1564
1565 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1566 {
1567         struct printjob *pjob = print_job_find(snum, jobid);
1568         int ret = -1;
1569         
1570         if (!pjob || !user) 
1571                 return False;
1572
1573         if (!pjob->spooled || pjob->sysjob == -1) 
1574                 return False;
1575
1576         if (!is_owner(user, snum, jobid) &&
1577             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1578                 DEBUG(3, ("pause denied by security descriptor\n"));
1579
1580                 /* BEGIN_ADMIN_LOG */
1581                 sys_adminlog( LOG_ERR, 
1582                         "Permission denied-- user not allowed to delete, \
1583 pause, or resume print job. User name: %s. Printer name: %s.",
1584                                 uidtoname(user->uid), PRINTERNAME(snum) );
1585                 /* END_ADMIN_LOG */
1586
1587                 *errcode = WERR_ACCESS_DENIED;
1588                 return False;
1589         }
1590
1591         /* need to pause the spooled entry */
1592         ret = (*(current_printif->job_pause))(snum, pjob);
1593
1594         if (ret != 0) {
1595                 *errcode = WERR_INVALID_PARAM;
1596                 return False;
1597         }
1598
1599         /* force update the database */
1600         print_cache_flush(snum);
1601
1602         /* Send a printer notify message */
1603
1604         notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1605
1606         /* how do we tell if this succeeded? */
1607
1608         return True;
1609 }
1610
1611 /****************************************************************************
1612  Resume a job.
1613 ****************************************************************************/
1614
1615 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1616 {
1617         struct printjob *pjob = print_job_find(snum, jobid);
1618         int ret;
1619         
1620         if (!pjob || !user)
1621                 return False;
1622
1623         if (!pjob->spooled || pjob->sysjob == -1)
1624                 return False;
1625
1626         if (!is_owner(user, snum, jobid) &&
1627             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1628                 DEBUG(3, ("resume denied by security descriptor\n"));
1629                 *errcode = WERR_ACCESS_DENIED;
1630
1631                 /* BEGIN_ADMIN_LOG */
1632                 sys_adminlog( LOG_ERR, 
1633                          "Permission denied-- user not allowed to delete, \
1634 pause, or resume print job. User name: %s. Printer name: %s.",
1635                         uidtoname(user->uid), PRINTERNAME(snum) );
1636                 /* END_ADMIN_LOG */
1637                 return False;
1638         }
1639
1640         ret = (*(current_printif->job_resume))(snum, pjob);
1641
1642         if (ret != 0) {
1643                 *errcode = WERR_INVALID_PARAM;
1644                 return False;
1645         }
1646
1647         /* force update the database */
1648         print_cache_flush(snum);
1649
1650         /* Send a printer notify message */
1651
1652         notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1653
1654         return True;
1655 }
1656
1657 /****************************************************************************
1658  Write to a print file.
1659 ****************************************************************************/
1660
1661 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1662 {
1663         int return_code;
1664         struct printjob *pjob = print_job_find(snum, jobid);
1665
1666         if (!pjob)
1667                 return -1;
1668         /* don't allow another process to get this info - it is meaningless */
1669         if (pjob->pid != local_pid)
1670                 return -1;
1671
1672         return_code = write(pjob->fd, buf, size);
1673         if (return_code>0) {
1674                 pjob->size += size;
1675                 pjob_store(snum, jobid, pjob);
1676         }
1677         return return_code;
1678 }
1679
1680 /****************************************************************************
1681  Check if the print queue has been updated recently enough.
1682 ****************************************************************************/
1683
1684 static BOOL print_cache_expired(int snum)
1685 {
1686         fstring key;
1687         time_t last_qscan_time, time_now = time(NULL);
1688         const char *printername = lp_const_servicename(snum);
1689         struct tdb_print_db *pdb = get_print_db_byname(printername);
1690
1691         if (!pdb)
1692                 return False;
1693
1694         slprintf(key, sizeof(key), "CACHE/%s", printername);
1695         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1696
1697         /*
1698          * Invalidate the queue for 3 reasons.
1699          * (1). last queue scan time == -1.
1700          * (2). Current time - last queue scan time > allowed cache time.
1701          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1702          * This last test picks up machines for which the clock has been moved
1703          * forward, an lpq scan done and then the clock moved back. Otherwise
1704          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1705          */
1706
1707         if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1708                         last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1709                 DEBUG(3, ("print cache expired for queue %s \
1710 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1711                         (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1712                 release_print_db(pdb);
1713                 return True;
1714         }
1715         release_print_db(pdb);
1716         return False;
1717 }
1718
1719 /****************************************************************************
1720  Get the queue status - do not update if db is out of date.
1721 ****************************************************************************/
1722
1723 static int get_queue_status(int snum, print_status_struct *status)
1724 {
1725         fstring keystr;
1726         TDB_DATA data, key;
1727         const char *printername = lp_const_servicename(snum);
1728         struct tdb_print_db *pdb = get_print_db_byname(printername);
1729         int len;
1730
1731         if (!pdb)
1732                 return 0;
1733
1734         if (status) {
1735                 ZERO_STRUCTP(status);
1736                 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1737                 key.dptr = keystr;
1738                 key.dsize = strlen(keystr);
1739                 data = tdb_fetch(pdb->tdb, key);
1740                 if (data.dptr) {
1741                         if (data.dsize == sizeof(print_status_struct))
1742                                 memcpy(status, data.dptr, sizeof(print_status_struct));
1743                         SAFE_FREE(data.dptr);
1744                 }
1745         }
1746         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1747         release_print_db(pdb);
1748         return (len == -1 ? 0 : len);
1749 }
1750
1751 /****************************************************************************
1752  Determine the number of jobs in a queue.
1753 ****************************************************************************/
1754
1755 int print_queue_length(int snum, print_status_struct *pstatus)
1756 {
1757         print_status_struct status;
1758         int len;
1759  
1760         /* make sure the database is up to date */
1761         if (print_cache_expired(snum))
1762                 print_queue_update(snum);
1763  
1764         /* also fetch the queue status */
1765         memset(&status, 0, sizeof(status));
1766         len = get_queue_status(snum, &status);
1767
1768         if (pstatus)
1769                 *pstatus = status;
1770
1771         return len;
1772 }
1773
1774 /***************************************************************************
1775  Allocate a jobid. Hold the lock for as short a time as possible.
1776 ***************************************************************************/
1777
1778 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1779 {
1780         int i;
1781         uint32 jobid;
1782
1783         *pjobid = (uint32)-1;
1784
1785         for (i = 0; i < 3; i++) {
1786                 /* Lock the database - only wait 20 seconds. */
1787                 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1788                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1789                         return False;
1790                 }
1791
1792                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1793                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1794                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1795                                                 printername ));
1796                                 return False;
1797                         }
1798                         jobid = 0;
1799                 }
1800
1801                 jobid = NEXT_JOBID(jobid);
1802
1803                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1804                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1805                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1806                         return False;
1807                 }
1808
1809                 /* We've finished with the INFO/nextjob lock. */
1810                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1811                                 
1812                 if (!print_job_exists(snum, jobid))
1813                         break;
1814         }
1815
1816         if (i > 2) {
1817                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1818                                 printername ));
1819                 /* Probably full... */
1820                 errno = ENOSPC;
1821                 return False;
1822         }
1823
1824         /* Store a dummy placeholder. */
1825         {
1826                 TDB_DATA dum;
1827                 dum.dptr = NULL;
1828                 dum.dsize = 0;
1829                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1830                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1831                                 jobid ));
1832                         return False;
1833                 }
1834         }
1835
1836         *pjobid = jobid;
1837         return True;
1838 }
1839
1840 /***************************************************************************
1841  Append a jobid to the 'jobs changed' list.
1842 ***************************************************************************/
1843
1844 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1845 {
1846         TDB_DATA data, key;
1847
1848         key.dptr = "INFO/jobs_changed";
1849         key.dsize = strlen(key.dptr);
1850         data.dptr = (char *)&jobid;
1851         data.dsize = 4;
1852
1853         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1854
1855         return (tdb_append(pdb->tdb, key, data) == 0);
1856 }
1857
1858 /***************************************************************************
1859  Start spooling a job - return the jobid.
1860 ***************************************************************************/
1861
1862 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1863 {
1864         uint32 jobid;
1865         char *path;
1866         struct printjob pjob;
1867         user_struct *vuser;
1868         const char *printername = lp_const_servicename(snum);
1869         struct tdb_print_db *pdb = get_print_db_byname(printername);
1870         int njobs;
1871
1872         errno = 0;
1873
1874         if (!pdb)
1875                 return (uint32)-1;
1876
1877         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1878                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1879                 release_print_db(pdb);
1880                 return (uint32)-1;
1881         }
1882
1883         if (!print_time_access_check(snum)) {
1884                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1885                 release_print_db(pdb);
1886                 return (uint32)-1;
1887         }
1888
1889         path = lp_pathname(snum);
1890
1891         /* see if we have sufficient disk space */
1892         if (lp_minprintspace(snum)) {
1893                 SMB_BIG_UINT dspace, dsize;
1894                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1895                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1896                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
1897                         release_print_db(pdb);
1898                         errno = ENOSPC;
1899                         return (uint32)-1;
1900                 }
1901         }
1902
1903         /* for autoloaded printers, check that the printcap entry still exists */
1904         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1905                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1906                 release_print_db(pdb);
1907                 errno = ENOENT;
1908                 return (uint32)-1;
1909         }
1910
1911         /* Insure the maximum queue size is not violated */
1912         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1913                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1914                         printername, njobs, lp_maxprintjobs(snum) ));
1915                 release_print_db(pdb);
1916                 errno = ENOSPC;
1917                 return (uint32)-1;
1918         }
1919
1920         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1921                         printername, njobs, lp_maxprintjobs(snum) ));
1922
1923         if (!allocate_print_jobid(pdb, snum, printername, &jobid))
1924                 goto fail;
1925
1926         /* create the database entry */
1927         
1928         ZERO_STRUCT(pjob);
1929         
1930         pjob.pid = local_pid;
1931         pjob.sysjob = -1;
1932         pjob.fd = -1;
1933         pjob.starttime = time(NULL);
1934         pjob.status = LPQ_SPOOLING;
1935         pjob.size = 0;
1936         pjob.spooled = False;
1937         pjob.smbjob = True;
1938         pjob.nt_devmode = nt_devmode;
1939         
1940         fstrcpy(pjob.jobname, jobname);
1941
1942         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1943                 fstrcpy(pjob.user, vuser->user.smb_name);
1944         } else {
1945                 fstrcpy(pjob.user, uidtoname(user->uid));
1946         }
1947
1948         fstrcpy(pjob.queuename, lp_const_servicename(snum));
1949
1950         /* we have a job entry - now create the spool file */
1951         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
1952                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
1953         pjob.fd = smb_mkstemp(pjob.filename);
1954
1955         if (pjob.fd == -1) {
1956                 if (errno == EACCES) {
1957                         /* Common setup error, force a report. */
1958                         DEBUG(0, ("print_job_start: insufficient permissions \
1959 to open spool file %s.\n", pjob.filename));
1960                 } else {
1961                         /* Normal case, report at level 3 and above. */
1962                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1963                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1964                 }
1965                 goto fail;
1966         }
1967
1968         pjob_store(snum, jobid, &pjob);
1969
1970         /* Update the 'jobs changed' entry used by print_queue_status. */
1971         add_to_jobs_changed(pdb, jobid);
1972
1973         /* Ensure we keep a rough count of the number of total jobs... */
1974         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
1975
1976         release_print_db(pdb);
1977
1978         return jobid;
1979
1980  fail:
1981         if (jobid != -1)
1982                 pjob_delete(snum, jobid);
1983
1984         release_print_db(pdb);
1985
1986         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
1987         return (uint32)-1;
1988 }
1989
1990 /****************************************************************************
1991  Update the number of pages spooled to jobid
1992 ****************************************************************************/
1993
1994 void print_job_endpage(int snum, uint32 jobid)
1995 {
1996         struct printjob *pjob = print_job_find(snum, jobid);
1997         if (!pjob)
1998                 return;
1999         /* don't allow another process to get this info - it is meaningless */
2000         if (pjob->pid != local_pid)
2001                 return;
2002
2003         pjob->page_count++;
2004         pjob_store(snum, jobid, pjob);
2005 }
2006
2007 /****************************************************************************
2008  Print a file - called on closing the file. This spools the job.
2009  If normal close is false then we're tearing down the jobs - treat as an
2010  error.
2011 ****************************************************************************/
2012
2013 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2014 {
2015         struct printjob *pjob = print_job_find(snum, jobid);
2016         int ret;
2017         SMB_STRUCT_STAT sbuf;
2018
2019         if (!pjob)
2020                 return False;
2021
2022         if (pjob->spooled || pjob->pid != local_pid)
2023                 return False;
2024
2025         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2026                 pjob->size = sbuf.st_size;
2027                 close(pjob->fd);
2028                 pjob->fd = -1;
2029         } else {
2030
2031                 /* 
2032                  * Not a normal close or we couldn't stat the job file,
2033                  * so something has gone wrong. Cleanup.
2034                  */
2035                 close(pjob->fd);
2036                 pjob->fd = -1;
2037                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2038                 goto fail;
2039         }
2040
2041         /* Technically, this is not quite right. If the printer has a separator
2042          * page turned on, the NT spooler prints the separator page even if the
2043          * print job is 0 bytes. 010215 JRR */
2044         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2045                 /* don't bother spooling empty files or something being deleted. */
2046                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2047                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2048                 unlink(pjob->filename);
2049                 pjob_delete(snum, jobid);
2050                 return True;
2051         }
2052
2053         ret = (*(current_printif->job_submit))(snum, pjob);
2054
2055         if (ret)
2056                 goto fail;
2057
2058         /* The print job has been sucessfully handed over to the back-end */
2059         
2060         pjob->spooled = True;
2061         pjob->status = LPQ_QUEUED;
2062         pjob_store(snum, jobid, pjob);
2063         
2064         /* make sure the database is up to date */
2065         if (print_cache_expired(snum))
2066                 print_queue_update(snum);
2067         
2068         return True;
2069
2070 fail:
2071
2072         /* The print job was not succesfully started. Cleanup */
2073         /* Still need to add proper error return propagation! 010122:JRR */
2074         unlink(pjob->filename);
2075         pjob_delete(snum, jobid);
2076         remove_from_jobs_changed(snum, jobid);
2077         return False;
2078 }
2079
2080 /****************************************************************************
2081  Get a snapshot of jobs in the system without traversing.
2082 ****************************************************************************/
2083
2084 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2085 {
2086         TDB_DATA data, key, cgdata;
2087         print_queue_struct *queue = NULL;
2088         uint32 qcount = 0;
2089         uint32 extra_count = 0;
2090         int total_count = 0;
2091         uint32 i;
2092         int max_reported_jobs = lp_max_reported_jobs(snum);
2093         BOOL ret = False;
2094
2095         /* make sure the database is up to date */
2096         if (print_cache_expired(snum))
2097                 print_queue_update(snum);
2098  
2099         *pcount = 0;
2100         *ppqueue = NULL;
2101
2102         ZERO_STRUCT(data);
2103         ZERO_STRUCT(cgdata);
2104         key.dptr = "INFO/linear_queue_array";
2105         key.dsize = strlen(key.dptr);
2106
2107         /* Get the stored queue data. */
2108         data = tdb_fetch(pdb->tdb, key);
2109
2110         if (data.dptr == NULL || data.dsize < 4)
2111                 qcount = 0;
2112         else
2113                 memcpy(&qcount, data.dptr, 4);
2114
2115         /* Get the changed jobs list. */
2116         key.dptr = "INFO/jobs_changed";
2117         key.dsize = strlen(key.dptr);
2118
2119         cgdata = tdb_fetch(pdb->tdb, key);
2120         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2121                 extra_count = cgdata.dsize/4;
2122
2123         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2124
2125         /* Allocate the queue size. */
2126         if (qcount == 0 && extra_count == 0)
2127                 goto out;
2128
2129         if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2130                 goto out;
2131
2132         /* Retrieve the linearised queue data. */
2133         for( i  = 0; i < qcount; i++) {
2134                 size_t len = 0;
2135                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2136                 len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, NULL, "ddddddff",
2137                                 &qjob,
2138                                 &qsize,
2139                                 &qpage_count,
2140                                 &qstatus,
2141                                 &qpriority,
2142                                 &qtime,
2143                                 queue[i].fs_user,
2144                                 queue[i].fs_file);
2145                 queue[i].job = qjob;
2146                 queue[i].size = qsize;
2147                 queue[i].page_count = qpage_count;
2148                 queue[i].status = qstatus;
2149                 queue[i].priority = qpriority;
2150                 queue[i].time = qtime;
2151         }
2152
2153         total_count = qcount;
2154
2155         /* Add in the changed jobids. */
2156         for( i  = 0; i < extra_count; i++) {
2157                 uint32 jobid;
2158                 struct printjob *pjob;
2159
2160                 memcpy(&jobid, &cgdata.dptr[i*4], 4);
2161                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2162                 pjob = print_job_find(snum, jobid);
2163                 if (!pjob) {
2164                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2165                         remove_from_jobs_changed(snum, jobid);
2166                         continue;
2167                 }
2168
2169                 queue[total_count].job = jobid;
2170                 queue[total_count].size = pjob->size;
2171                 queue[total_count].page_count = pjob->page_count;
2172                 queue[total_count].status = pjob->status;
2173                 queue[total_count].priority = 1;
2174                 fstrcpy(queue[total_count].fs_user, pjob->user);
2175                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2176                 total_count++;
2177         }
2178
2179         /* Sort the queue by submission time otherwise they are displayed
2180            in hash order. */
2181
2182         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2183
2184         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2185
2186         if (max_reported_jobs && total_count > max_reported_jobs)
2187                 total_count = max_reported_jobs;
2188
2189         *ppqueue = queue;
2190         *pcount = total_count;
2191
2192         ret = True;
2193
2194   out:
2195
2196         SAFE_FREE(data.dptr);
2197         SAFE_FREE(cgdata.dptr);
2198         return ret;
2199 }
2200
2201 /****************************************************************************
2202  Get a printer queue listing.
2203  set queue = NULL and status = NULL if you just want to update the cache
2204 ****************************************************************************/
2205
2206 int print_queue_status(int snum, 
2207                        print_queue_struct **ppqueue,
2208                        print_status_struct *status)
2209 {
2210         fstring keystr;
2211         TDB_DATA data, key;
2212         const char *printername;
2213         struct tdb_print_db *pdb;
2214         int count = 0;
2215
2216         /* make sure the database is up to date */
2217
2218         if (print_cache_expired(snum))
2219                 print_queue_update(snum);
2220
2221         /* return if we are done */
2222         if ( !ppqueue || !status )
2223                 return 0;
2224
2225         *ppqueue = NULL;
2226         printername = lp_const_servicename(snum);
2227         pdb = get_print_db_byname(printername);
2228
2229         if (!pdb)
2230                 return 0;
2231
2232         /*
2233          * Fetch the queue status.  We must do this first, as there may
2234          * be no jobs in the queue.
2235          */
2236
2237         ZERO_STRUCTP(status);
2238         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2239         key.dptr = keystr;
2240         key.dsize = strlen(keystr);
2241         data = tdb_fetch(pdb->tdb, key);
2242         if (data.dptr) {
2243                 if (data.dsize == sizeof(*status)) {
2244                         memcpy(status, data.dptr, sizeof(*status));
2245                 }
2246                 SAFE_FREE(data.dptr);
2247         }
2248
2249         /*
2250          * Now, fetch the print queue information.  We first count the number
2251          * of entries, and then only retrieve the queue if necessary.
2252          */
2253
2254         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2255                 release_print_db(pdb);
2256                 return 0;
2257         }
2258
2259         release_print_db(pdb);
2260         return count;
2261 }
2262
2263 /****************************************************************************
2264  Pause a queue.
2265 ****************************************************************************/
2266
2267 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2268 {
2269         int ret;
2270         
2271         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2272                 *errcode = WERR_ACCESS_DENIED;
2273                 return False;
2274         }
2275
2276         ret = (*(current_printif->queue_pause))(snum);
2277
2278         if (ret != 0) {
2279                 *errcode = WERR_INVALID_PARAM;
2280                 return False;
2281         }
2282
2283         /* force update the database */
2284         print_cache_flush(snum);
2285
2286         /* Send a printer notify message */
2287
2288         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2289
2290         return True;
2291 }
2292
2293 /****************************************************************************
2294  Resume a queue.
2295 ****************************************************************************/
2296
2297 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2298 {
2299         int ret;
2300
2301         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2302                 *errcode = WERR_ACCESS_DENIED;
2303                 return False;
2304         }
2305
2306         ret = (*(current_printif->queue_resume))(snum);
2307
2308         if (ret != 0) {
2309                 *errcode = WERR_INVALID_PARAM;
2310                 return False;
2311         }
2312
2313         /* make sure the database is up to date */
2314         if (print_cache_expired(snum))
2315                 print_queue_update(snum);
2316
2317         /* Send a printer notify message */
2318
2319         notify_printer_status(snum, PRINTER_STATUS_OK);
2320
2321         return True;
2322 }
2323
2324 /****************************************************************************
2325  Purge a queue - implemented by deleting all jobs that we can delete.
2326 ****************************************************************************/
2327
2328 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2329 {
2330         print_queue_struct *queue;
2331         print_status_struct status;
2332         int njobs, i;
2333         BOOL can_job_admin;
2334
2335         /* Force and update so the count is accurate (i.e. not a cached count) */
2336         print_queue_update(snum);
2337         
2338         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2339         njobs = print_queue_status(snum, &queue, &status);
2340
2341         for (i=0;i<njobs;i++) {
2342                 BOOL owner = is_owner(user, snum, queue[i].job);
2343
2344                 if (owner || can_job_admin) {
2345                         print_job_delete1(snum, queue[i].job);
2346                 }
2347         }
2348
2349         SAFE_FREE(queue);
2350
2351         return True;
2352 }