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