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