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